aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-07-12 11:40:46 +0200
committerMartin Liska <mliska@suse.cz>2021-07-12 11:40:46 +0200
commit993a6fb652c7b82ef4fa8a3fdc0dbfe05987d829 (patch)
treee367854da02f55b4abf387b818fda2f504f198ef /gcc
parent7445abec5d383d37a2f827657dafa12053179c6e (diff)
parent9b8b37d1b6301855213b8d4860feaeb74d464c6b (diff)
downloadgcc-993a6fb652c7b82ef4fa8a3fdc0dbfe05987d829.zip
gcc-993a6fb652c7b82ef4fa8a3fdc0dbfe05987d829.tar.gz
gcc-993a6fb652c7b82ef4fa8a3fdc0dbfe05987d829.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog921
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog1426
-rw-r--r--gcc/ada/Make-generated.in2
-rw-r--r--gcc/ada/Makefile.rtl20
-rw-r--r--gcc/ada/adaint.c4
-rw-r--r--gcc/ada/adaint.h6
-rw-r--r--gcc/ada/aspects.ads13
-rw-r--r--gcc/ada/atree.ads2
-rw-r--r--gcc/ada/checks.adb120
-rw-r--r--gcc/ada/checks.ads4
-rw-r--r--gcc/ada/comperr.adb6
-rw-r--r--gcc/ada/debug.adb13
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst40
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst28
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst20
-rw-r--r--gcc/ada/einfo-utils.adb69
-rw-r--r--gcc/ada/einfo-utils.ads29
-rw-r--r--gcc/ada/einfo.ads42
-rw-r--r--gcc/ada/errout.adb39
-rw-r--r--gcc/ada/exp_aggr.adb393
-rw-r--r--gcc/ada/exp_attr.adb48
-rw-r--r--gcc/ada/exp_ch11.adb83
-rw-r--r--gcc/ada/exp_ch3.adb76
-rw-r--r--gcc/ada/exp_ch4.adb43
-rw-r--r--gcc/ada/exp_ch5.adb156
-rw-r--r--gcc/ada/exp_ch6.adb154
-rw-r--r--gcc/ada/exp_ch6.ads7
-rw-r--r--gcc/ada/exp_ch7.adb520
-rw-r--r--gcc/ada/exp_ch7.ads11
-rw-r--r--gcc/ada/exp_ch9.adb28
-rw-r--r--gcc/ada/exp_dbug.adb11
-rw-r--r--gcc/ada/exp_dbug.ads409
-rw-r--r--gcc/ada/exp_disp.adb125
-rw-r--r--gcc/ada/exp_dist.adb1
-rw-r--r--gcc/ada/exp_imgv.adb11
-rw-r--r--gcc/ada/exp_pakd.adb8
-rw-r--r--gcc/ada/exp_prag.adb31
-rw-r--r--gcc/ada/exp_put_image.adb349
-rw-r--r--gcc/ada/exp_util.adb8
-rw-r--r--gcc/ada/exp_util.ads4
-rw-r--r--gcc/ada/fe.h24
-rw-r--r--gcc/ada/freeze.adb40
-rw-r--r--gcc/ada/gcc-interface/decl.c24
-rw-r--r--gcc/ada/gcc-interface/system.ads4
-rw-r--r--gcc/ada/gcc-interface/trans.c6
-rw-r--r--gcc/ada/gcc-interface/utils.c3
-rw-r--r--gcc/ada/gen_il-fields.ads2
-rw-r--r--gcc/ada/gen_il-gen-gen_entities.adb52
-rw-r--r--gcc/ada/gen_il-gen-gen_nodes.adb20
-rw-r--r--gcc/ada/gen_il-gen.adb40
-rw-r--r--gcc/ada/gen_il-gen.ads18
-rw-r--r--gcc/ada/gen_il-internals.ads2
-rw-r--r--gcc/ada/gen_il-types.ads2
-rw-r--r--gcc/ada/gnat-style.texi1691
-rw-r--r--gcc/ada/gnat1drv.adb30
-rw-r--r--gcc/ada/gnat_rm.texi2155
-rw-r--r--gcc/ada/gnat_ugn.texi910
-rw-r--r--gcc/ada/gsocket.h1
-rw-r--r--gcc/ada/impunit.adb6
-rw-r--r--gcc/ada/inline.adb14
-rw-r--r--gcc/ada/krunch.adb17
-rw-r--r--gcc/ada/layout.adb87
-rw-r--r--gcc/ada/layout.ads7
-rw-r--r--gcc/ada/lib-load.adb35
-rw-r--r--gcc/ada/lib-writ.adb19
-rw-r--r--gcc/ada/lib-writ.ads3
-rw-r--r--gcc/ada/lib.adb21
-rw-r--r--gcc/ada/lib.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__alpha.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__android.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__hppa.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__mips.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__riscv.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__sparc.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux__x32.ads7
-rw-r--r--gcc/ada/libgnarl/s-osinte__aix.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__android.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__darwin.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__dragonfly.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__freebsd.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__gnu.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__hpux-dce.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__hpux.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__linux.ads2
-rw-r--r--gcc/ada/libgnarl/s-osinte__lynxos178e.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__qnx.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__rtems.ads4
-rw-r--r--gcc/ada/libgnarl/s-osinte__solaris.ads5
-rw-r--r--gcc/ada/libgnarl/s-osinte__vxworks.ads7
-rw-r--r--gcc/ada/libgnarl/s-qnx.ads5
-rw-r--r--gcc/ada/libgnarl/s-tassta.adb5
-rw-r--r--gcc/ada/libgnat/a-cbdlli.adb4
-rw-r--r--gcc/ada/libgnat/a-cbhama.adb8
-rw-r--r--gcc/ada/libgnat/a-cbhase.adb4
-rw-r--r--gcc/ada/libgnat/a-cbmutr.adb4
-rw-r--r--gcc/ada/libgnat/a-cborma.adb8
-rw-r--r--gcc/ada/libgnat/a-cborse.adb8
-rw-r--r--gcc/ada/libgnat/a-cdlili.adb226
-rw-r--r--gcc/ada/libgnat/a-cfdlli.adb32
-rw-r--r--gcc/ada/libgnat/a-cfdlli.ads49
-rw-r--r--gcc/ada/libgnat/a-cfhama.adb181
-rw-r--r--gcc/ada/libgnat/a-cfhama.ads96
-rw-r--r--gcc/ada/libgnat/a-cfhase.adb212
-rw-r--r--gcc/ada/libgnat/a-cfhase.ads17
-rw-r--r--gcc/ada/libgnat/a-cfinve.adb48
-rw-r--r--gcc/ada/libgnat/a-cfinve.ads44
-rw-r--r--gcc/ada/libgnat/a-cforma.adb236
-rw-r--r--gcc/ada/libgnat/a-cforma.ads96
-rw-r--r--gcc/ada/libgnat/a-cforse.adb269
-rw-r--r--gcc/ada/libgnat/a-cforse.ads25
-rw-r--r--gcc/ada/libgnat/a-coboho.adb34
-rw-r--r--gcc/ada/libgnat/a-coboho.ads6
-rw-r--r--gcc/ada/libgnat/a-cobove.adb8
-rw-r--r--gcc/ada/libgnat/a-cofove.adb32
-rw-r--r--gcc/ada/libgnat/a-cofove.ads44
-rw-r--r--gcc/ada/libgnat/a-cofuma.ads8
-rw-r--r--gcc/ada/libgnat/a-cofuse.ads7
-rw-r--r--gcc/ada/libgnat/a-cofuve.ads7
-rw-r--r--gcc/ada/libgnat/a-cohama.adb14
-rw-r--r--gcc/ada/libgnat/a-cohama.ads8
-rw-r--r--gcc/ada/libgnat/a-cohase.adb14
-rw-r--r--gcc/ada/libgnat/a-cohase.ads9
-rw-r--r--gcc/ada/libgnat/a-conhel.adb13
-rw-r--r--gcc/ada/libgnat/a-ngelfu.ads2
-rw-r--r--gcc/ada/libgnat/a-stobbu.adb53
-rw-r--r--gcc/ada/libgnat/a-stobbu.ads34
-rw-r--r--gcc/ada/libgnat/a-stobfi.adb118
-rw-r--r--gcc/ada/libgnat/a-stobfi.ads66
-rw-r--r--gcc/ada/libgnat/a-stoubu.adb148
-rw-r--r--gcc/ada/libgnat/a-stoubu.ads73
-rw-r--r--gcc/ada/libgnat/a-stoufi.adb123
-rw-r--r--gcc/ada/libgnat/a-stoufi.ads72
-rw-r--r--gcc/ada/libgnat/a-stoufo.adb155
-rw-r--r--gcc/ada/libgnat/a-stoufo.ads72
-rw-r--r--gcc/ada/libgnat/a-stouut.adb272
-rw-r--r--gcc/ada/libgnat/a-stouut.ads107
-rw-r--r--gcc/ada/libgnat/a-strfix.adb138
-rw-r--r--gcc/ada/libgnat/a-strunb.ads29
-rw-r--r--gcc/ada/libgnat/a-strunb__shared.ads11
-rw-r--r--gcc/ada/libgnat/a-sttebu.ads3
-rw-r--r--gcc/ada/libgnat/a-stteou.ads193
-rw-r--r--gcc/ada/libgnat/a-textio.adb13
-rw-r--r--gcc/ada/libgnat/a-uncdea.ads5
-rw-r--r--gcc/ada/libgnat/a-witeio.adb13
-rw-r--r--gcc/ada/libgnat/a-ztexio.adb13
-rw-r--r--gcc/ada/libgnat/g-debpoo.adb2
-rw-r--r--gcc/ada/libgnat/g-socket.adb46
-rw-r--r--gcc/ada/libgnat/g-socket.ads46
-rw-r--r--gcc/ada/libgnat/g-sothco.ads7
-rw-r--r--gcc/ada/libgnat/s-atocou.ads1
-rw-r--r--gcc/ada/libgnat/s-atocou__builtin.adb20
-rw-r--r--gcc/ada/libgnat/s-os_lib.adb92
-rw-r--r--gcc/ada/libgnat/s-os_lib.ads33
-rw-r--r--gcc/ada/libgnat/s-osprim__darwin.adb4
-rw-r--r--gcc/ada/libgnat/s-osprim__posix.adb4
-rw-r--r--gcc/ada/libgnat/s-osprim__posix2008.adb4
-rw-r--r--gcc/ada/libgnat/s-osprim__rtems.adb4
-rw-r--r--gcc/ada/libgnat/s-osprim__x32.adb3
-rw-r--r--gcc/ada/libgnat/s-parame.ads7
-rw-r--r--gcc/ada/libgnat/s-parame__ae653.ads7
-rw-r--r--gcc/ada/libgnat/s-parame__hpux.ads7
-rw-r--r--gcc/ada/libgnat/s-parame__posix2008.ads193
-rw-r--r--gcc/ada/libgnat/s-parame__vxworks.ads15
-rw-r--r--gcc/ada/libgnat/s-rident.ads1
-rw-r--r--gcc/ada/make.adb9
-rw-r--r--gcc/ada/osint.adb8
-rw-r--r--gcc/ada/par-ch10.adb28
-rw-r--r--gcc/ada/par-ch5.adb12
-rw-r--r--gcc/ada/par-ch6.adb155
-rw-r--r--gcc/ada/par-load.adb38
-rw-r--r--gcc/ada/par-prag.adb1
-rw-r--r--gcc/ada/par.adb8
-rw-r--r--gcc/ada/repinfo-input.adb4
-rw-r--r--gcc/ada/repinfo.adb61
-rw-r--r--gcc/ada/repinfo.ads7
-rw-r--r--gcc/ada/restrict.adb20
-rw-r--r--gcc/ada/restrict.ads10
-rw-r--r--gcc/ada/rtinit.c18
-rw-r--r--gcc/ada/rtsfind.adb8
-rw-r--r--gcc/ada/rtsfind.ads13
-rw-r--r--gcc/ada/s-oscons-tmplt.c30
-rw-r--r--gcc/ada/scng.adb20
-rw-r--r--gcc/ada/sem.ads2
-rw-r--r--gcc/ada/sem_aggr.adb9
-rw-r--r--gcc/ada/sem_attr.adb32
-rw-r--r--gcc/ada/sem_case.adb287
-rw-r--r--gcc/ada/sem_cat.ads2
-rw-r--r--gcc/ada/sem_ch12.adb12
-rw-r--r--gcc/ada/sem_ch13.adb310
-rw-r--r--gcc/ada/sem_ch13.ads22
-rw-r--r--gcc/ada/sem_ch3.adb260
-rw-r--r--gcc/ada/sem_ch3.ads5
-rw-r--r--gcc/ada/sem_ch4.adb78
-rw-r--r--gcc/ada/sem_ch5.adb259
-rw-r--r--gcc/ada/sem_ch6.adb312
-rw-r--r--gcc/ada/sem_ch7.adb9
-rw-r--r--gcc/ada/sem_ch8.adb126
-rw-r--r--gcc/ada/sem_ch9.adb16
-rw-r--r--gcc/ada/sem_disp.adb71
-rw-r--r--gcc/ada/sem_eval.adb7
-rw-r--r--gcc/ada/sem_prag.adb97
-rw-r--r--gcc/ada/sem_prag.ads1
-rw-r--r--gcc/ada/sem_res.adb82
-rw-r--r--gcc/ada/sem_type.ads3
-rw-r--r--gcc/ada/sem_util.adb643
-rw-r--r--gcc/ada/sem_util.ads123
-rw-r--r--gcc/ada/sigtramp-vxworks-target.h (renamed from gcc/ada/sigtramp-vxworks-target.inc)2
-rw-r--r--gcc/ada/sigtramp-vxworks.c2
-rw-r--r--gcc/ada/sinfo-cn.adb1
-rw-r--r--gcc/ada/sinfo.ads32
-rw-r--r--gcc/ada/sinput-l.adb24
-rw-r--r--gcc/ada/snames.ads-tmpl4
-rw-r--r--gcc/ada/sprint.adb8
-rw-r--r--gcc/ada/style.adb4
-rw-r--r--gcc/ada/targparm.ads10
-rw-r--r--gcc/ada/tbuild.adb72
-rw-r--r--gcc/ada/tbuild.ads36
-rw-r--r--gcc/ada/ttypes.ads2
-rw-r--r--gcc/ada/uname.adb133
-rw-r--r--gcc/analyzer/ChangeLog298
-rw-r--r--gcc/analyzer/analyzer.h5
-rw-r--r--gcc/analyzer/diagnostic-manager.cc35
-rw-r--r--gcc/analyzer/engine.cc59
-rw-r--r--gcc/analyzer/exploded-graph.h4
-rw-r--r--gcc/analyzer/program-state.cc1
-rw-r--r--gcc/analyzer/region-model-impl-calls.cc39
-rw-r--r--gcc/analyzer/region-model-manager.cc313
-rw-r--r--gcc/analyzer/region-model.cc376
-rw-r--r--gcc/analyzer/region-model.h56
-rw-r--r--gcc/analyzer/region.cc230
-rw-r--r--gcc/analyzer/region.h125
-rw-r--r--gcc/analyzer/sm-file.cc15
-rw-r--r--gcc/analyzer/sm-malloc.cc10
-rw-r--r--gcc/analyzer/sm-pattern-test.cc24
-rw-r--r--gcc/analyzer/sm-sensitive.cc18
-rw-r--r--gcc/analyzer/sm-signal.cc21
-rw-r--r--gcc/analyzer/sm-taint.cc8
-rw-r--r--gcc/analyzer/sm.cc14
-rw-r--r--gcc/analyzer/sm.h34
-rw-r--r--gcc/analyzer/store.cc653
-rw-r--r--gcc/analyzer/store.h157
-rw-r--r--gcc/analyzer/svalue.cc395
-rw-r--r--gcc/analyzer/svalue.h266
-rw-r--r--gcc/btfout.c2
-rw-r--r--gcc/builtins.c411
-rw-r--r--gcc/builtins.h5
-rw-r--r--gcc/c-family/ChangeLog29
-rw-r--r--gcc/c-family/c-ada-spec.c40
-rw-r--r--gcc/c-family/c-common.h19
-rw-r--r--gcc/c-family/c-format.c12
-rw-r--r--gcc/c-family/c-omp.c151
-rw-r--r--gcc/c/ChangeLog10
-rw-r--r--gcc/c/c-objc-common.c15
-rw-r--r--gcc/c/c-parser.c4
-rw-r--r--gcc/calls.c58
-rw-r--r--gcc/cfgloopmanip.c1
-rw-r--r--gcc/collect2.c40
-rw-r--r--gcc/common.opt9
-rw-r--r--gcc/common/config/gcn/gcn-common.c2
-rw-r--r--gcc/config.gcc10
-rw-r--r--gcc/config.in12
-rw-r--r--gcc/config/aarch64/aarch64-builtins.c23
-rw-r--r--gcc/config/aarch64/aarch64.c3
-rw-r--r--gcc/config/arm/arm-builtins.c33
-rw-r--r--gcc/config/arm/arm.c4
-rw-r--r--gcc/config/arm/arm_neon.h259
-rw-r--r--gcc/config/arm/neon.md9
-rw-r--r--gcc/config/arm/vec-common.md9
-rw-r--r--gcc/config/darwin.h12
-rw-r--r--gcc/config/frv/frv-protos.h118
-rw-r--r--gcc/config/gcn/gcn.c171
-rw-r--r--gcc/config/gcn/gcn.h10
-rw-r--r--gcc/config/h8300/h8300-protos.h6
-rw-r--r--gcc/config/h8300/h8300.c53
-rw-r--r--gcc/config/h8300/jumpcall.md27
-rw-r--r--gcc/config/h8300/predicates.md2
-rw-r--r--gcc/config/h8300/shiftrotate.md280
-rw-r--r--gcc/config/i386/darwin.h22
-rw-r--r--gcc/config/i386/darwin32-biarch.h22
-rw-r--r--gcc/config/i386/darwin64-biarch.h22
-rwxr-xr-xgcc/config/i386/gcc-auto-profile41
-rw-r--r--gcc/config/i386/i386-expand.c734
-rw-r--r--gcc/config/i386/i386-features.c195
-rw-r--r--gcc/config/i386/i386-options.c2
-rw-r--r--gcc/config/i386/i386-protos.h4
-rw-r--r--gcc/config/i386/i386.c19
-rw-r--r--gcc/config/i386/i386.h13
-rw-r--r--gcc/config/i386/i386.md105
-rw-r--r--gcc/config/i386/mmx.md204
-rw-r--r--gcc/config/i386/predicates.md16
-rw-r--r--gcc/config/i386/sse.md54
-rw-r--r--gcc/config/m32r/m32r-protos.h8
-rw-r--r--gcc/config/m32r/m32r.c6
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c6
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def30
-rw-r--r--gcc/config/rs6000/rs6000-call.c57
-rw-r--r--gcc/config/rs6000/rs6000.c34
-rw-r--r--gcc/config/rs6000/rs6000.md140
-rw-r--r--gcc/config/rs6000/vsx.md4
-rw-r--r--gcc/config/stormy16/stormy16-protos.h6
-rw-r--r--gcc/config/stormy16/stormy16.c4
-rwxr-xr-xgcc/configure166
-rw-r--r--gcc/configure.ac96
-rw-r--r--gcc/cp/ChangeLog170
-rw-r--r--gcc/cp/constexpr.c4
-rw-r--r--gcc/cp/constraint.cc10
-rw-r--r--gcc/cp/coroutines.cc33
-rw-r--r--gcc/cp/cp-tree.h40
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/cp/decl2.c25
-rw-r--r--gcc/cp/error.c9
-rw-r--r--gcc/cp/except.c9
-rw-r--r--gcc/cp/init.c43
-rw-r--r--gcc/cp/module.cc7
-rw-r--r--gcc/cp/parser.c401
-rw-r--r--gcc/cp/parser.h6
-rw-r--r--gcc/cp/pt.c86
-rw-r--r--gcc/d/ChangeLog12
-rw-r--r--gcc/d/d-codegen.cc7
-rw-r--r--gcc/d/toir.cc32
-rw-r--r--gcc/dbgcnt.def1
-rw-r--r--gcc/diagnostic.c122
-rw-r--r--gcc/diagnostic.h26
-rw-r--r--gcc/doc/extend.texi3
-rw-r--r--gcc/doc/install.texi4
-rw-r--r--gcc/doc/invoke.texi24
-rw-r--r--gcc/doc/md.texi25
-rw-r--r--gcc/dwarf2ctf.c4
-rw-r--r--gcc/dwarf2out.c4
-rw-r--r--gcc/exec-tool.in8
-rw-r--r--gcc/expr.c13
-rw-r--r--gcc/fold-const.c46
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/frontend-passes.c4
-rw-r--r--gcc/gcc.c61
-rw-r--r--gcc/genpreds.c8
-rw-r--r--gcc/gimple-array-bounds.cc336
-rw-r--r--gcc/gimple-fold.c18
-rw-r--r--gcc/gimple-loop-interchange.cc7
-rw-r--r--gcc/gimple-pretty-print.c17
-rw-r--r--gcc/gimple-ssa-sprintf.c11
-rw-r--r--gcc/gimple-ssa-warn-alloca.c26
-rw-r--r--gcc/gimple-ssa-warn-restrict.c152
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/input.c459
-rw-r--r--gcc/input.h33
-rw-r--r--gcc/internal-fn.def3
-rw-r--r--gcc/ipa-sra.c15
-rw-r--r--gcc/ira-conflicts.c93
-rw-r--r--gcc/ira-int.h2
-rw-r--r--gcc/ira.c128
-rw-r--r--gcc/match.pd146
-rw-r--r--gcc/omp-low.c55
-rw-r--r--gcc/optabs.def2
-rw-r--r--gcc/opts.c1
-rw-r--r--gcc/params.opt4
-rw-r--r--gcc/range-op.cc18
-rw-r--r--gcc/recog.c137
-rw-r--r--gcc/recog.h2
-rw-r--r--gcc/testsuite/ChangeLog565
-rw-r--r--gcc/testsuite/c-c++-common/Warray-bounds-10.c114
-rw-r--r--gcc/testsuite/c-c++-common/Warray-bounds-3.c4
-rw-r--r--gcc/testsuite/c-c++-common/Warray-bounds-4.c12
-rw-r--r--gcc/testsuite/c-c++-common/Warray-bounds-9.c144
-rw-r--r--gcc/testsuite/c-c++-common/dump-ada-spec-14.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-24.c12
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_test.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/explicit-spec1.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto24.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto42.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist75.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist80.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept70.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr78765.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/auto-array.C36
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-access2.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5a.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires26.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires27.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-uneval16.C22
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/auto1.C3
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-1.C553
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-2.C553
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-3.C40
-rw-r--r--gcc/testsuite/g++.dg/opt/pr99728.C50
-rw-r--r--gcc/testsuite/g++.dg/pr95768.C2
-rw-r--r--gcc/testsuite/g++.dg/template/access41.C24
-rw-r--r--gcc/testsuite/g++.dg/template/access41a.C29
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae14.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr101256.C28
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-10.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-11.C23
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-12.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-13.C23
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-17.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-20.C12
-rw-r--r--gcc/testsuite/g++.dg/warn/uninit-pr55881.C34
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-29.c22
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-31.c8
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-32.c26
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-52.c6
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-53.c6
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-58.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-63.c6
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-66.c12
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-69.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-71.c7
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-71.h46
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-72.c7
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-73.c7
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-74.c7
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-75.c12
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-76.c35
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-77.c135
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-78.c109
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-79.c112
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c24
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c46
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c49
-rw-r--r--gcc/testsuite/gcc.dg/Wobjsize-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-34.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-43.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-47.c14
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-61.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/clobbers-1.c98
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/clobbers-2.c72
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memset-1.c118
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c107
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-8.c11
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-13.c329
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-14.c302
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf.exp5
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf.exp5
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr57351.c1
-rw-r--r--gcc/testsuite/gcc.dg/format/c90-printf-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/format/gcc_diag-10.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr101066.c20
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c21
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr101223.c44
-rw-r--r--gcc/testsuite/gcc.dg/pr101266.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr101294.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr101403.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr79214.c22
-rw-r--r--gcc/testsuite/gcc.dg/pragma-diag-10.c20
-rw-r--r--gcc/testsuite/gcc.dg/pragma-diag-9.c141
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr100329.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr100519.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr100778.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr101278.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c18
-rw-r--r--gcc/testsuite/gcc.dg/uninit-suppress_3.c98
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-72.c29
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-73.c29
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-74.c31
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr34195.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f16.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f64.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/pr98435.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-pr101286.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-1.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-5.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXpd.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXps.c50
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXpd.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXps.c50
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f_cond_move.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-5.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/divmod-9.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesdec128kl.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesdec256kl.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesenc128kl.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesenc256kl.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-10a.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-10b.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-11a.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-11b.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-11c.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-12a.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-12b.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-12c.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-2.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-3.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-4a.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-4b.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-5a.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-5b.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-6a.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-6b.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-6c.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-7a.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-7b.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-7c.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-8a.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-8b.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-8c.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-9a.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-9b.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100865-9c.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101044.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr92658-avx512vl.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-vec-set-1a.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-vec-set-2a.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXpd.c34
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXps.c34
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXpd.c34
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXps.c34
-rw-r--r--gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c11
-rw-r--r--gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/pr100760.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/pr100761.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/pr100762.c25
-rw-r--r--gcc/testsuite/gcc.target/powerpc/div-vectorize-1.c46
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-cmove.c58
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-minmax.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mma-builtin-7.c26
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mma-builtin-8.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mod-vectorize.c46
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mul-vectorize-1.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mul-vectorize-2.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c27
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr101273.d39
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr101282.d23
-rw-r--r--gcc/testsuite/gfortran.dg/implied_do_io_7.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/pr101264.f9094
-rw-r--r--gcc/testsuite/gfortran.dg/pr101267.f9023
-rw-r--r--gcc/testsuite/lib/gcc-defs.exp34
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp45
-rw-r--r--gcc/testsuite/lib/target-supports.exp10
-rw-r--r--gcc/trans-mem.c8
-rw-r--r--gcc/tree-diagnostic.c77
-rw-r--r--gcc/tree-pretty-print.c26
-rw-r--r--gcc/tree-pretty-print.h1
-rw-r--r--gcc/tree-ssa-ccp.c6
-rw-r--r--gcc/tree-ssa-dse.c10
-rw-r--r--gcc/tree-ssa-loop-im.c88
-rw-r--r--gcc/tree-ssa-phiopt.c300
-rw-r--r--gcc/tree-ssa-strlen.c105
-rw-r--r--gcc/tree-ssa-uninit.c4
-rw-r--r--gcc/tree-vect-loop-manip.c2
-rw-r--r--gcc/tree-vect-loop.c50
-rw-r--r--gcc/tree-vect-slp-patterns.c192
-rw-r--r--gcc/tree-vect-slp.c292
-rw-r--r--gcc/tree-vect-stmts.c92
618 files changed, 25427 insertions, 10636 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 52d2397..6e6aaf0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,924 @@
+2021-07-09 Roger Sayle <roger@nextmovesoftware.com>
+ Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*divmodsi4_const): Optimize SImode
+ divmod of a constant numerator with new define_insn_and_split.
+
+2021-07-09 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR target/100152
+ * config/i386/i386-expand.c (ix86_expand_call): If a call is
+ to a non-local-binding, or local but to a public symbol, then
+ assume that it might be indirected via the lazy symbol binder.
+ Mark R10 and R10 as clobbered in that case.
+
+2021-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/101377
+ * gcc.c (ASM_DEBUG_DWARF_OPTION): Set again to --gdwarf2 in
+ the case where HAVE_AS_WORKING_DWARF_N_FLAG is not defined
+ and HAVE_LD_BROKEN_PE_DWARF5 is defined.
+
+2021-07-09 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*udivmodsi4_pow2_zext_1): Limit the
+ log2 range of operands[3] to [1,31].
+ (*udivmodsi4_pow2_zext_2): Ditto. Correct insn RTX pattern.
+
+2021-07-09 Sergei Trofimovich <siarheit@google.com>
+
+ * doc/md.texi: Don't split @smallexample in multiple @groups.
+
+2021-07-09 Sergei Trofimovich <siarheit@google.com>
+
+ * doc/md.texi: Add missing 'see' word.
+
+2021-07-09 Andrew Pinski <apinski@marvell.com>
+
+ * tree-ssa-phiopt.c (phiopt_early_allow): Change arguments
+ to take sequence and gimple_match_op. Accept the case where
+ op is a SSA_NAME and one statement in the sequence.
+ Also allow constants.
+ (gimple_simplify_phiopt): Always pass a sequence to resimplify.
+ Update call to phiopt_early_allow. Discard the sequence if not
+ used.
+
+2021-07-09 Xi Ruoyao <xry111@mengyan1223.wang>
+
+ PR target/100760
+ PR target/100761
+ PR target/100762
+ * config/mips/mips.c (mips_const_insns): Use MSA_SUPPORTED_MODE_P
+ instead of ISA_HAS_MSA.
+ (mips_expand_vec_unpack): Likewise.
+ (mips_expand_vector_init): Likewise.
+
+2021-07-09 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/vsx.md (mods_<mode>): Rename to...
+ (mod<mode>3): ... this.
+ (modu_<mode>): Rename to...
+ (umod<mode>3): ... this.
+ * config/rs6000/rs6000-builtin.def (MODS_V2DI, MODS_V4SI, MODU_V2DI,
+ MODU_V4SI): Adjust.
+
+2021-07-08 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/shiftrotate.md (variable shifts): Expose condition
+ code handling for the test before the loop.
+
+2021-07-08 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/101066
+ * ipa-sra.c (class isra_call_summary): New member
+ m_before_any_store, initialize it in the constructor.
+ (isra_call_summary::dump): Dump the new field.
+ (ipa_sra_call_summaries::duplicate): Copy it.
+ (process_scan_results): Set it.
+ (isra_write_edge_summary): Stream it.
+ (isra_read_edge_summary): Likewise.
+ (param_splitting_across_edge): Only override
+ safe_to_import_accesses if m_before_any_store is set.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/101374
+ * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref):
+ Use Object Size Type 0 instead of 1.
+
+2021-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vect-loop.c (vectorizable_reduction): Remove always-true
+ if condition.
+
+2021-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * match.pd: Simplify an extend-operate-truncate sequence involving
+ a POLY_INT_CST.
+
+2021-07-08 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/40210
+ * match.pd (bswap optimizations): Simplify (bswap(x)>>C1)&C2 as
+ (x>>C3)&C2 when possible. Simplify bswap(x)>>C1 as ((T)x)>>C2
+ when possible. Simplify bswap(x)&C1 as (x>>C2)&C1 when 0<=C1<=255.
+
+2021-07-08 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/100637
+ * config/i386/i386-expand.c (ix86_expand_sse_unpack):
+ Handle V4QI mode.
+ * config/i386/mmx.md (V_32): New mode iterator.
+ (mov<V_32:mode>): Use V_32 mode iterator.
+ (*mov<V_32:mode>_internal): Ditto.
+ (*push<V_32:mode>2_rex64): Ditto.
+ (*push<V_32:mode>2): Ditto.
+ (movmisalign<V_32:mode>): Ditto.
+ (mmx_<any_shiftrt:insn>v1si3): New insn pattern.
+ (sse4_1_<any_extend:code>v2qiv2hi2): Ditto.
+ (vec_unpacks_lo_v4qi): New expander.
+ (vec_unpacks_hi_v4qi): Ditto.
+ (vec_unpacku_lo_v4qi): Ditto.
+ (vec_unpacku_hi_v4qi): Ditto.
+ * config/i386/i386.h (VALID_SSE2_REG_MODE): Add V1SImode.
+ (VALID_INT_MODE_P): Ditto.
+
+2021-07-08 Michael Meissner <meissner@linux.ibm.com>
+
+ PR target/100809
+ * config/rs6000/rs6000.md (udivti3): New insn.
+ (divti3): New insn.
+ (umodti3): New insn.
+ (modti3): New insn.
+
+2021-07-07 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/100137
+ PR tree-optimization/99121
+ PR tree-optimization/97027
+ * builtins.c (access_ref::access_ref): Also set offmax.
+ (access_ref::offset_in_range): Define new function.
+ (access_ref::add_offset): Set offmax.
+ (access_ref::inform_access): Handle access_none.
+ (handle_mem_ref): Clear ostype.
+ (compute_objsize_r): Handle ASSERT_EXPR.
+ * builtins.h (struct access_ref): Add offmax member.
+ * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Use
+ compute_objsize() and simplify.
+
+2021-07-07 Peter Bergner <bergner@linux.ibm.com>
+
+ * config/rs6000/rs6000-call.c (mma_init_builtins): Use VSX_BUILTIN_LXVP
+ and VSX_BUILTIN_STXVP.
+
+2021-07-07 Martin Sebor <msebor@redhat.com>
+
+ PR target/101363
+ * config/aarch64/aarch64.c (aarch64_simd_lane_bounds): Remove
+ a stray %K from error_at() missed in r12-2088.
+
+2021-07-07 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/99728
+ * tree-ssa-loop-im.c (gather_mem_refs_stmt): Record
+ aggregate copies.
+ (mem_refs_may_alias_p): Add assert we handled aggregate
+ copies elsewhere.
+ (sm_seq_valid_bb): Give up when running into aggregate copies.
+ (ref_indep_loop_p): Handle aggregate copies as never
+ being invariant themselves but allow other refs to be
+ disambiguated against them.
+ (can_sm_ref_p): Do not try to apply store-motion to aggregate
+ copies.
+
+2021-07-06 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR debug/101283
+ * dwarf2ctf.c (ctf_get_AT_data_member_location): Multiply by 8 to get
+ number of bits.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * gimple-pretty-print.c (percent_G_format): Remove.
+ * tree-diagnostic.c (default_tree_printer): Remove calls.
+ * tree-pretty-print.c (percent_K_format): Remove.
+ * tree-pretty-print.h (percent_K_format): Remove.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * config/aarch64/aarch64-builtins.c (aarch64_simd_expand_builtin):
+ Remove %K and use error_at.
+ (aarch64_expand_fcmla_builtin): Same.
+ (aarch64_expand_builtin_tme): Same.
+ (aarch64_expand_builtin_memtag): Same.
+ * config/arm/arm-builtins.c (arm_expand_acle_builtin): Same.
+ (arm_expand_builtin): Same.
+ * config/arm/arm.c (bounds_check): Same.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * builtins.c (warn_string_no_nul): Remove %G.
+ (maybe_warn_for_bound): Same.
+ (warn_for_access): Same.
+ (check_access): Same.
+ (check_strncat_sizes): Same.
+ (expand_builtin_strncat): Same.
+ (expand_builtin_strncmp): Same.
+ (expand_builtin): Same.
+ (expand_builtin_object_size): Same.
+ (warn_dealloc_offset): Same.
+ (maybe_emit_free_warning): Same.
+ * calls.c (maybe_warn_alloc_args_overflow): Same.
+ (maybe_warn_nonstring_arg): Same.
+ (maybe_warn_rdwr_sizes): Same.
+ * expr.c (expand_expr_real_1): Remove %K.
+ * gimple-fold.c (gimple_fold_builtin_strncpy): Remove %G.
+ (gimple_fold_builtin_strncat): Same.
+ * gimple-ssa-sprintf.c (format_directive): Same.
+ (handle_printf_call): Same.
+ * gimple-ssa-warn-alloca.c (pass_walloca::execute): Same.
+ * gimple-ssa-warn-restrict.c (maybe_diag_overlap): Same.
+ (maybe_diag_access_bounds): Same. Call gimple_location.
+ (check_bounds_or_overlap): Same.
+ * trans-mem.c (ipa_tm_scan_irr_block): Remove %K. Simplify.
+ * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Remove %G.
+ * tree-ssa-strlen.c (maybe_warn_overflow): Same.
+ (maybe_diag_stxncpy_trunc): Same.
+ (handle_builtin_stxncpy_strncat): Same.
+ (maybe_warn_pointless_strcmp): Same.
+ * tree-ssa-uninit.c (maybe_warn_operand): Same.
+
+2021-07-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97194
+ * config/i386/predicates.md (vec_setm_operand): Enable
+ register_operand for TARGET_SSE4_1.
+ * config/i386/mmx.md (vec_setv2hi): Use vec_setm_operand
+ as operand 2 predicate. Call ix86_expand_vector_set_var
+ for non-constant index operand.
+ (vec_setv4qi): Use vec_setm_mmx_operand as operand 2 predicate.
+ Call ix86_expand_vector_set_var for non-constant index operand.
+
+2021-07-06 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/jumpcall.md (*branch): When possible, generate
+ the comparison in CCZN mode.
+ * config/h8300/predicates.md (simple_memory_operand): Reject all
+ auto-increment addressing modes.
+
+2021-07-06 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR bootstrap/100246
+ * config/i386/i386.h (struct stringop_algs): Define a CTOR for
+ this type.
+
+2021-07-06 Richard Biener <rguenther@suse.de>
+
+ * doc/md.texi (vec_fmaddsub<mode>4): Document.
+ (vec_fmsubadd<mode>4): Likewise.
+ * optabs.def (vec_fmaddsub$a4): Add.
+ (vec_fmsubadd$a4): Likewise.
+ * internal-fn.def (IFN_VEC_FMADDSUB): Add.
+ (IFN_VEC_FMSUBADD): Likewise.
+ * tree-vect-slp-patterns.c (addsub_pattern::recognize):
+ Refactor to handle IFN_VEC_FMADDSUB and IFN_VEC_FMSUBADD.
+ (addsub_pattern::build): Likewise.
+ * tree-vect-slp.c (vect_optimize_slp): CFN_VEC_FMADDSUB
+ and CFN_VEC_FMSUBADD are not transparent for permutes.
+ * config/i386/sse.md (vec_fmaddsub<mode>4): New expander.
+ (vec_fmsubadd<mode>4): Likewise.
+
+2021-07-06 Richard Biener <rguenther@suse.de>
+
+ * doc/invoke.texi (fmove-loop-stores): Document.
+ * common.opt (fmove-loop-stores): New option.
+ * opts.c (default_options_table): Enable -fmove-loop-stores
+ at -O1 but not -Og.
+ * tree-ssa-loop-im.c (pass_lim::execute): Pass
+ flag_move_loop_stores instead of true to
+ loop_invariant_motion_in_fun.
+
+2021-07-06 Iain Sandoe <iain@sandoe.co.uk>
+
+ * doc/install.texi: Document --with-dsymutil.
+
+2021-07-06 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101256
+ * dbgcnt.def (phiopt_edge_range): New counter.
+ * tree-ssa-phiopt.c (replace_phi_edge_with_variable):
+ Check to make sure the new name is defined in the same
+ bb as the conditional before duplicating range info.
+ Also add debug counter.
+
+2021-07-06 Kewen Lin <linkw@linux.ibm.com>
+
+ PR rtl-optimization/100328
+ * config/i386/i386-options.c (ix86_option_override_internal):
+ Set param_ira_consider_dup_in_all_alts to 0.
+
+2021-07-06 Kewen Lin <linkw@linux.ibm.com>
+
+ PR rtl-optimization/100328
+ * doc/invoke.texi (ira-consider-dup-in-all-alts): Document new
+ parameter.
+ * ira.c (ira_get_dup_out_num): Adjust as parameter
+ param_ira_consider_dup_in_all_alts.
+ * params.opt (ira-consider-dup-in-all-alts): New.
+ * ira-conflicts.c (process_regs_for_copy): Add one parameter
+ single_input_op_has_cstr_p.
+ (get_freq_for_shuffle_copy): New function.
+ (add_insn_allocno_copies): Adjust as single_input_op_has_cstr_p.
+ * ira-int.h (ira_get_dup_out_num): Add one bool parameter.
+
+2021-07-05 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/shiftrotate.md (shift-by-variable patterns): Update to
+ generate condition code aware RTL directly.
+
+2021-07-05 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101039
+ * match.pd (A CMP 0 ? A : -A): New patterns.
+ * tree-ssa-phiopt.c (abs_replacement): Delete function.
+ (tree_ssa_phiopt_worker): Don't call abs_replacement.
+ Update comment about abs_replacement.
+
+2021-07-05 Andrew Pinski <apinski@marvell.com>
+
+ * tree-ssa-phiopt.c (gimple_simplify_phiopt):
+ If "A ? B : C" fails to simplify, try "(!A) ? C : B".
+
+2021-07-05 Andrew Pinski <apinski@marvell.com>
+
+ * tree-ssa-phiopt.c (match_simplify_replacement):
+ Add early_p argument. Call gimple_simplify_phiopt
+ instead of gimple_simplify.
+ (tree_ssa_phiopt_worker): Update call to
+ match_simplify_replacement and allow unconditionally.
+ (phiopt_early_allow): New function.
+ (gimple_simplify_phiopt): New function.
+
+2021-07-05 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/101237
+ * fold-const.c (negate_expr_p): Remove call to element_mode
+ and TREE_MODE/TREE_TYPE when calling HONOR_SIGNED_ZEROS,
+ HONOR_SIGN_DEPENDENT_ROUNDING, and HONOR_SNANS.
+ (fold_negate_expr_1): Likewise.
+ (const_unop): Likewise.
+ (fold_cond_expr_with_comparison): Likewise.
+ (fold_binary_loc): Likewise.
+ (fold_ternary_loc): Likewise.
+ (tree_call_nonnegative_warnv_p): Likewise.
+ * match.pd (-(A + B) -> (-B) - A): Likewise.
+
+2021-07-05 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure.ac: Handle --with-dsymutil in the same way as we
+ do for the assembler and linker. (DEFAULT_DSYMUTIL): New.
+ Extract the type and version for the dsymutil configured or
+ found by the default searches.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+ * collect2.c (do_dsymutil): Handle locating dsymutil in the
+ same way as for the assembler and linker.
+ * config/darwin.h (DSYMUTIL): Delete.
+ * gcc.c: Report a configured dsymutil correctly.
+ * exec-tool.in: Allow for dsymutil.
+
+2021-07-05 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_split_mmx_punpck):
+ Handle V4QI and V2HI modes.
+ (expand_vec_perm_blend): Allow 4-byte vector modes with TARGET_SSE4_1.
+ Handle V4QI mode. Emit mmx_pblendvb32 for 4-byte modes.
+ (expand_vec_perm_pshufb): Rewrite to use switch statemets.
+ Handle 4-byte dual operands with TARGET_XOP and single operands
+ with TARGET_SSSE3. Emit mmx_ppermv32 for TARGET_XOP and
+ mmx_pshufbv4qi3 for TARGET_SSSE3.
+ (expand_vec_perm_pblendv): Allow 4-byte vector modes with TARGET_SSE4_1.
+ (expand_vec_perm_interleave2): Allow 4-byte vector modes.
+ (expand_vec_perm_pshufb2): Allow 4-byte vector modes with TARGET_SSSE3.
+ (expand_vec_perm_even_odd_1): Handle V4QI mode.
+ (expand_vec_perm_broadcast_1): Handle V4QI mode.
+ (ix86_vectorize_vec_perm_const): Handle V4QI mode.
+ * config/i386/mmx.md (mmx_ppermv32): New insn pattern.
+ (mmx_pshufbv4qi3): Ditto.
+ (*mmx_pblendw32): Ditto.
+ (*mmx_pblendw64): Rename from *mmx_pblendw.
+ (mmx_punpckhbw_low): New insn_and_split pattern.
+ (mmx_punpcklbw_low): Ditto.
+
+2021-07-05 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop-manip.c (vect_loop_versioning): Do not
+ set LOOP_C_INFINITE on the vectorized loop.
+
+2021-07-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/101291
+ * cfgloopmanip.c (loop_version): Set the loop copy of the
+ versioned loop to the new loop.
+
+2021-07-04 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR target/100269
+ * config.gcc: Ensure that Darwin biarch definitions are
+ added before i386.h.
+ * config/i386/darwin.h (TARGET_64BIT): Remove.
+ (PR80556_WORKAROUND): New.
+ (REAL_LIBGCC_SPEC): Amend to use PR80556_WORKAROUND.
+ (DARWIN_SUBARCH_SPEC): New.
+ * config/i386/darwin32-biarch.h (TARGET_64BIT_DEFAULT,
+ TARGET_BI_ARCH, PR80556_WORKAROUND): New.
+ (REAL_LIBGCC_SPEC): Remove.
+ * config/i386/darwin64-biarch.h (TARGET_64BIT_DEFAULT,
+ TARGET_BI_ARCH, PR80556_WORKAROUND): New.
+ (REAL_LIBGCC_SPEC): Remove.
+
+2021-07-03 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/101294
+ * expr.c (store_constructor): Don't use vec_duplicate on vector.
+
+2021-07-02 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/98871
+ PR middle-end/98512
+ * diagnostic.c (get_any_inlining_info): New.
+ (update_effective_level_from_pragmas): Handle inlining context.
+ (diagnostic_enabled): Same.
+ (diagnostic_report_diagnostic): Same.
+ * diagnostic.h (struct diagnostic_info): Add ctor.
+ (struct diagnostic_context): Add new member.
+ * tree-diagnostic.c (set_inlining_locations): New.
+ (tree_diagnostics_defaults): Set new callback pointer.
+
+2021-07-02 Peter Bergner <bergner@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin.def (BU_MMA_PAIR_LD, BU_MMA_PAIR_ST):
+ New macros.
+ (__builtin_vsx_lxvp, __builtin_vsx_stxvp): New built-ins.
+ * config/rs6000/rs6000-call.c (rs6000_gimple_fold_mma_builtin): Expand
+ lxvp and stxvp built-ins.
+ (mma_init_builtins): Handle lxvp and stxvp built-ins.
+ (builtin_function_type): Likewise.
+ * doc/extend.texi (__builtin_vsx_lxvp, __builtin_mma_stxvp): Document.
+
+2021-07-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/h8300-protos.h (compute_a_shift_cc): Accept
+ additional argument for the code.
+ * config/h8300/h8300.c (compute_a_shift_cc): Accept additional
+ argument for the code. Just return if the ZN bits are useful or
+ not rather than the old style CC_* enums.
+ * config/h8300/shiftrotate.md (shiftqi_noscratch): Move before
+ more generic shiftqi patterns.
+ (shifthi_noscratch, shiftsi_noscratch): Similarly.
+ (shiftqi_noscratch_set_flags): New pattern.
+ (shifthi_noscratch_set_flags, shiftsi_noscratch_set_flags): Likewise.
+
+2021-07-02 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/101223
+ * range-op.cc (build_lt): Add -1 for signed values.
+ (built_gt): Subtract -1 for signed values.
+
+2021-07-02 David Faust <david.faust@oracle.com>
+
+ * btfout.c (get_btf_kind): Support BTF_KIND_FLOAT.
+ (btf_asm_type): Likewise.
+
+2021-07-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/h8300-protos.h (output_a_shift): Make first argument
+ an array of rtx rather than a pointer to rtx. Add code argument.
+ (compute_a_shift_length): Similarly.
+ * config/h8300/h8300.c (h8300_shift_costs): Adjust now that the
+ shift itself isn't an operand. Create dummy operand[0] to carry
+ a mode and pass a suitable rtx code to compute_a_shift_length.
+ (get_shift_alg): Adjust operand number of clobber in output templates.
+ (output_a_shift): Make first argument an array of rtx rather than
+ a pointer to rtx. Add code argument for the type of shift.
+ Adjust now that the shift itself is no longer an operand.
+ (compute_a_shift_length): Similarly.
+ * config/h8300/shiftrotate.md (shiftqi, shifthi, shiftsi): Use an
+ iterator rather than nshift_operator.
+ (shiftqi_noscratch, shifthi_noscratch, shiftsi_noscratch): Likewise.
+ (shiftqi_clobber_flags): Adjust to API changes in output_a_shift
+ and compute_a_shift_length.
+ (shiftqi_noscratch_clobber_flags): Likewise.
+ (shifthi_noscratch_clobber_flags): Likewise.
+ (shiftsi_noscratch_clobber_flags): Likewise.
+
+2021-07-02 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR debug/101283
+ * config/darwin.h (DSYMUTIL_SPEC): Do not try to run
+ dsymutil for BTF/CTF.
+
+2021-07-02 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR debug/101283
+ * config/darwin.h (CTF_INFO_SECTION_NAME): Update the
+ segment to include BTF.
+ (BTF_INFO_SECTION_NAME): New.
+
+2021-07-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/m32r/m32r-protos.h (call_operand): Adjust return type.
+ (small_data_operand, memreg_operand, small_insn_p): Likewise.
+ * config/m32r/m32r.c (call_operand): Adjust return type.
+ (small_data_operand, memreg_operand): Likewise.
+
+2021-07-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/frv/frv-protos.h (integer_register_operand): Adjust return
+ type.
+ (frv_load_operand, gpr_or_fpr_operand, gpr_no_subreg_operand): Likewise.
+ (fpr_or_int6_operand, gpr_or_int_operand); Likewise.
+ (gpr_or_int12_operand, gpr_or_int10_operand); Likewise.
+ (move_source_operand, move_destination_operand): Likewise.
+ (condexec_source_operand, condexec_dest_operand): Likewise.
+ (lr_operand, gpr_or_memory_operand, fpr_or_memory_operand): Likewise.
+ (reg_or_0_operand, fcc_operand, icc_operand, cc_operand): Likewise.
+ (fcr_operand, icr_operand, cr_operand, call_operand): Likewise.
+ (fpr_operand, even_reg_operand, odd_reg_operand): Likewise.
+ (even_gpr_operand, odd_gpr_operand, quad_fpr_operand): Likewise.
+ (even_fpr_operand, odd_fpr_operand): Likewise.
+ (dbl_memory_one_insn_operand, dbl_memory_two_insn_operand): Likewise.
+ (int12_operand, int6_operand, int5_operand, uint5_operand): Likewise.
+ (uint4_operand, uint1_operand, int_2word_operand): Likewise
+ (upper_int16_operand, uint16_operand, symbolic_operand): Likewise.
+ (relational_operator, float_relational_operator): Likewise.
+ (ccr_eqne_operator, minmax_operator): Likewise.
+ (condexec_si_binary_operator, condexec_si_media_operator): Likewise.
+ (condexec_si_divide_operator, condexec_si_unary_operator): Likewise.
+ (condexec_sf_conv_operator, condexec_sf_add_operator): Likewise.
+ (intop_compare_operator, acc_operand, even_acc_operand): Likewise.
+ (quad_acc_operand, accg_operand): Likewise.
+
+2021-07-02 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/stormy16/stormy16-protos.h (xstormy16_below_100_symbol): Change
+ return type to a bool.
+ (nonimmediate_nonstack_operand): Likewise.
+ (xstormy16_splittable_below100_operand): Likewise.
+ * config/stormy16/stormy16.c (xstormy16_below_100_symbol): Fix
+ return type.
+ (xstormy16_splittable_below100_operand): Likewise.
+
+2021-07-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101293
+ * tree-ssa-loop-im.c (mem_ref_hasher::equal): Compare MEM_REF bases
+ with combined offsets.
+ (gather_mem_refs_stmt): Hash MEM_REFs as if their offset were
+ combined with the rest of the offset.
+
+2021-07-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/i386/i386.c (asm_preferred_eh_data_format): Always use the
+ PIC encodings for PE-COFF targets.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/101286
+ * config/i386/i386-expand.c (ix86_broadcast_from_integer_constant):
+ Return nullptr for TImode inner mode.
+
+2021-07-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101280
+ PR tree-optimization/101173
+ * gimple-loop-interchange.cc
+ (tree_loop_interchange::valid_data_dependences): Properly
+ guard all dependence checks with DDR_REVERSED_P or its
+ inverse.
+
+2021-07-02 Hongyu Wang <hongyu.wang@intel.com>
+
+ * config/i386/i386-expand.c (ix86_expand_builtin):
+ Add branch to clear odata when ZF is set for asedecenc_expand
+ and wideaesdecenc_expand.
+
+2021-07-02 Eugene Rozenfeld <erozen@microsoft.com>
+
+ * config/i386/gcc-auto-profile: regenerate
+
+2021-07-02 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/sse.md (trunc<mode><pmov_dst_4>2): Refined to ..
+ (trunc<mode><pmov_dst_4_lower>2): this.
+
+2021-07-01 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic.h (diagnostic_context::m_file_cache): New field.
+ * input.c (class fcache): Rename to...
+ (class file_cache_slot): ...this, making most members private and
+ prefixing fields with "m_".
+ (file_cache_slot::get_file_path): New accessor.
+ (file_cache_slot::get_use_count): New accessor.
+ (file_cache_slot::missing_trailing_newline_p): New accessor.
+ (file_cache_slot::inc_use_count): New.
+ (fcache_buffer_size): Move to...
+ (file_cache_slot::buffer_size): ...here.
+ (fcache_line_record_size): Move to...
+ (file_cache_slot::line_record_size): ...here.
+ (fcache_tab): Delete, in favor of global_dc->m_file_cache.
+ (fcache_tab_size): Move to file_cache::num_file_slots.
+ (diagnostic_file_cache_init): Update for move of fcache_tab
+ to global_dc->m_file_cache.
+ (diagnostic_file_cache_fini): Likewise.
+ (lookup_file_in_cache_tab): Convert to...
+ (file_cache::lookup_file): ...this.
+ (diagnostics_file_cache_forcibly_evict_file): Update for move of
+ fcache_tab to global_dc->m_file_cache, moving most of
+ implementation to...
+ (file_cache::forcibly_evict_file): ...this new function and...
+ (file_cache_slot::evict): ...this new function.
+ (evicted_cache_tab_entry): Convert to...
+ (file_cache::evicted_cache_tab_entry): ...this.
+ (add_file_to_cache_tab): Convert to...
+ (file_cache::add_file): ...this, moving bulk of implementation
+ to...
+ (file_cache_slot::create): ..this new function.
+ (file_cache::file_cache): New.
+ (file_cache::~file_cache): New.
+ (lookup_or_add_file_to_cache_tab): Convert to...
+ (file_cache::lookup_or_add_file): ..this new function.
+ (fcache::fcache): Rename to...
+ (file_cache_slot::file_cache_slot): ...this, adding "m_" prefixes
+ to fields.
+ (fcache::~fcache): Rename to...
+ (file_cache_slot::~file_cache_slot): ...this, adding "m_" prefixes
+ to fields.
+ (needs_read): Convert to...
+ (file_cache_slot::needs_read_p): ...this.
+ (needs_grow): Convert to...
+ (file_cache_slot::needs_grow_p): ...this.
+ (maybe_grow): Convert to...
+ (file_cache_slot::maybe_grow): ...this.
+ (read_data): Convert to...
+ (file_cache_slot::read_data): ...this.
+ (maybe_read_data): Convert to...
+ (file_cache_slot::maybe_read_data): ...this.
+ (get_next_line): Convert to...
+ (file_cache_slot::get_next_line): ...this.
+ (goto_next_line): Convert to...
+ (file_cache_slot::goto_next_line): ...this.
+ (read_line_num): Convert to...
+ (file_cache_slot::read_line_num): ...this.
+ (location_get_source_line): Update for moving of globals to
+ global_dc->m_file_cache.
+ (location_missing_trailing_newline): Likewise.
+ * input.h (class file_cache_slot): New forward decl.
+ (class file_cache): New.
+
+2021-07-01 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_maybe_emit_fp_cmove): Add IEEE
+ 128-bit floating point conditional move support.
+ (have_compare_and_set_mask): Add IEEE 128-bit floating point
+ types.
+ * config/rs6000/rs6000.md (mov<mode>cc, IEEE128 iterator): New insn.
+ (mov<mode>cc_p10, IEEE128 iterator): New insn.
+ (mov<mode>cc_invert_p10, IEEE128 iterator): New insn.
+ (fpmask<mode>, IEEE128 iterator): New insn.
+ (xxsel<mode>, IEEE128 iterator): New insn.
+
+2021-07-01 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR debug/101283
+ * config/darwin.h (CTF_INFO_SECTION_NAME): New.
+
+2021-07-01 H.J. Lu <hjl.tools@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_expand_vector_init_duplicate):
+ Make it global.
+ * config/i386/i386-protos.h (ix86_expand_vector_init_duplicate):
+ New prototype.
+ * config/i386/sse.md (INT_BROADCAST_MODE): New mode iterator.
+ (vec_duplicate<mode>): New expander.
+
+2021-07-01 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/100865
+ * config/i386/i386-expand.c (ix86_expand_vector_init_duplicate):
+ New prototype.
+ (ix86_byte_broadcast): New function.
+ (ix86_convert_const_wide_int_to_broadcast): Likewise.
+ (ix86_expand_move): Convert CONST_WIDE_INT to broadcast if mode
+ size is 16 bytes or bigger.
+ (ix86_broadcast_from_integer_constant): New function.
+ (ix86_expand_vector_move): Convert CONST_WIDE_INT and CONST_VECTOR
+ to broadcast if mode size is 16 bytes or bigger.
+ * config/i386/i386-protos.h (ix86_gen_scratch_sse_rtx): New
+ prototype.
+ * config/i386/i386.c (ix86_gen_scratch_sse_rtx): New function.
+
+2021-07-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/predicates.md (ix86_endbr_immediate_operand):
+ Return true/false instead of 1/0.
+ (movq_parallel): Ditto.
+
+2021-07-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ * recog.c (general_operand): Return true/false instead of 1/0.
+ (register_operand): Ditto.
+ (immediate_operand): Ditto.
+ (const_int_operand): Ditto.
+ (const_scalar_int_operand): Ditto.
+ (const_double_operand): Ditto.
+ (push_operand): Ditto.
+ (pop_operand): Ditto.
+ (memory_operand): Ditto.
+ (indirect_operand): Ditto.
+
+2021-07-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ * genpreds.c (write_predicate_subfunction):
+ Change the type of written subfunction to bool.
+ (write_one_predicate_function):
+ Change the type of written function to bool.
+ (write_tm_preds_h): Ditto.
+ * recog.h (*insn_operand_predicate_fn): Change the type to bool.
+ * recog.c (general_operand): Change the type to bool.
+ (address_operand): Ditto.
+ (register_operand): Ditto.
+ (pmode_register_operand): Ditto.
+ (scratch_operand): Ditto.
+ (immediate_operand): Ditto.
+ (const_int_operand): Ditto.
+ (const_scalar_int_operand): Ditto.
+ (const_double_operand): Ditto.
+ (nonimmediate_operand): Ditto.
+ (nonmemory_operand): Ditto.
+ (push_operand): Ditto.
+ (pop_operand): Ditto.
+ (memory_operand): Ditto.
+ (indirect_operand): Ditto.
+ (ordered_comparison_operator): Ditto.
+ (comparison_operator): Ditto.
+ * config/i386/i386-expand.c (ix86_expand_sse_cmp):
+ Change the type of indirect predicate function to bool.
+ * config/rs6000/rs6000.c (easy_vector_constant):
+ Change the type to bool.
+ * config/mips/mips-protos.h (m16_based_address_p):
+ Change the type of operand 3 to bool.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101280
+ PR tree-optimization/101173
+ * gimple-loop-interchange.cc
+ (tree_loop_interchange::valid_data_dependences): Revert
+ previous change and instead correctly handle DDR_REVERSED_P
+ dependence.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101278
+ * tree-ssa-dse.c (dse_classify_store): First check for
+ uses, then ignore stmt for chaining purposes.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/100778
+ * tree-vect-slp.c (vect_schedule_slp_node): Do not place trapping
+ vectorized ops ahead of their scalar BB.
+
+2021-07-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/101044
+ * config/i386/i386.md (*nabs<dwi>2_doubleword):
+ New insn_and_split pattern.
+ (*nabs<dwi>2_1): Ditto.
+ * config/i386/i386-features.c
+ (general_scalar_chain::compute_convert_gain):
+ Handle (NEG (ABS (...))) RTX. Rewrite src code
+ scanner as switch statement.
+ (general_scalar_chain::convert_insn):
+ Handle (NEG (ABS (...))) RTX.
+ (general_scalar_to_vector_candidate_p):
+ Detect (NEG (ABS (...))) RTX. Reorder case statements
+ for (AND (NOT (...) ...)) fallthrough.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101178
+ * tree-vect-slp.c (slpg_vertex::materialize): Remove.
+ (slpg::perm_in): Add.
+ (slpg::get_perm_in): Remove.
+ (slpg::get_perm_materialized): Add.
+ (vect_optimize_slp): Handle VEC_PERM nodes more optimally
+ during permute propagation and materialization.
+
+2021-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/101266
+ * dwarf2out.c (loc_list_from_tree_1): Handle COMPOUND_LITERAL_EXPR.
+
+2021-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/94366
+ * omp-low.c (lower_rec_input_clauses): Rename is_fp_and_or to
+ is_truth_op, set it for TRUTH_*IF_EXPR regardless of new_var's type,
+ use boolean_type_node instead of integer_type_node as NE_EXPR type.
+ (lower_reduction_clauses): Likewise.
+
+2021-06-30 Hafiz Abid Qadeer <abidh@codesourcery.com>
+
+ * config/gcn/gcn.c: Include dwarf2.h.
+ (gcn_addr_space_debug): New function.
+ (TARGET_ADDR_SPACE_DEBUG): New hook.
+
+2021-06-30 Hafiz Abid Qadeer <abidh@codesourcery.com>
+
+ * common/config/gcn/gcn-common.c
+ (gcn_option_optimization_table): Change OPT_fomit_frame_pointer to -O3.
+ * config/gcn/gcn.c (gcn_expand_prologue): Prefer the frame pointer
+ when emitting CFI.
+ (gcn_expand_prologue): Prefer the frame pointer when emitting CFI.
+ (gcn_frame_pointer_rqd): New function.
+ (TARGET_FRAME_POINTER_REQUIRED): New hook.
+
+2021-06-30 Hafiz Abid Qadeer <abidh@codesourcery.com>
+
+ * config/gcn/gcn.c (move_callee_saved_registers): Emit CFI notes for
+ prologue register saves.
+ (gcn_debug_unwind_info): Use UI_DWARF2.
+ (gcn_dwarf_register_number): Map DWARF_LINK_REGISTER to DWARF PC.
+ (gcn_dwarf_register_span): DWARF_LINK_REGISTER doesn't span.
+ * config/gcn/gcn.h: (DWARF_FRAME_RETURN_COLUMN): New define.
+ (DWARF_LINK_REGISTER): New define.
+ (FIRST_PSEUDO_REGISTER): Increment.
+ (FIXED_REGISTERS): Add entry for DWARF_LINK_REGISTER.
+ (CALL_USED_REGISTERS): Likewise.
+ (REGISTER_NAMES): Likewise.
+
+2021-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101267
+ * tree-vect-stmts.c (vect_check_scalar_mask): Adjust
+ API and use SLP compatible interface of vect_is_simple_use.
+ Reject not vectorized SLP defs for callers that do not support
+ that.
+ (vect_check_store_rhs): Handle masked stores and pass down
+ the appropriate operator index.
+ (vectorizable_call): Adjust.
+ (vectorizable_store): Likewise.
+ (vectorizable_load): Likewise. Handle SLP pecularity of
+ masked loads.
+ (vect_is_simple_use): Remove special-casing of masked stores.
+
+2021-06-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * common.opt (foffload): Remove help as Driver only.
+ * gcc.c (display_help): Add -foffload.
+
+2021-06-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * gcc.c (close_at_file, execute): Replace alloca by XALLOCAVEC.
+ (check_offload_target_name): Fix splitting OFFLOAD_TARGETS into
+ a candidate list; better inform no offload target is configured
+ and fix hint extraction when passed target is not '\0' at [len].
+ * common.opt (foffload): Add tailing '.'.
+ (foffload-options): Likewise; fix flag name in the help string.
+
+2021-06-30 prathamesh.kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/66791
+ * config/arm/arm_neon.h: Move vabs intrinsics before vcage_f32.
+ (vcage_f32): Gate comparison on __FAST_MATH__.
+ (vcageq_f32): Likewise.
+ (vcale_f32): Likewise.
+ (vcaleq_f32): Likewise.
+ (vcagt_f32): Likewise.
+ (vcagtq_f32): Likewise.
+ (vcalt_f32): Likewise.
+ (vcaltq_f32): Likewise.
+ (vcage_f16): Likewise.
+ (vcageq_f16): Likewise.
+ (vcale_f16): Likewise.
+ (vcaleq_f16): Likewise.
+ (vcagt_f16): Likewise.
+ (vcagtq_f16): Likewise.
+ (vcalt_f16): Likewise.
+ (vcaltq_f16): Likewise.
+
+2021-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101264
+ * tree-vect-slp.c (vect_optimize_slp): Propagate the
+ computed perm_in to all "any" permute successors
+ we cannot de-duplicate immediately.
+
+2021-06-30 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101248
+ * config/i386/sse.md
+ (avx512f_sfixupimm<mode><sd_maskz_name><round_saeonly_name>):
+ Refined to ..
+ (avx512f_sfixupimm<mode><maskz_scalar_name><round_saeonly_name>):
+ this.
+ (avx512f_sfixupimm<mode>_mask<round_saeonly_name>"): Refined.
+ * config/i386/subst.md (maskz_scalar): New define_subst.
+ (maskz_scalar_name): New subst_attr.
+ (maskz_scalar_op5): Ditto.
+ (round_saeonly_maskz_scalar_op5): Ditto.
+ (round_saeonly_maskz_scalar_operand5): Ditto.
+
+2021-06-30 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_xcoff_section_type_flags):
+ Increase code CSECT alignment to at least 32 bytes.
+ * config/rs6000/xcoff.h (TEXT_SECTION_ASM_OP): Add 32 byte
+ alignment designation.
+
2021-06-29 Sergei Trofimovich <siarheit@google.com>
* doc/generic.texi: Fix s/net yet/not yet/ typo.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 80bc3a6..d01e523 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210630
+20210712
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index f07cc96..9b5629c 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1429 @@
+2021-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils.c (finish_subprog_decl): Remove obsolete line.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_put_image.adb (Make_Put_Image_Name): Fix style.
+ (Image_Should_Call_Put_Image): Likewise.
+ (Build_Image_Call): Likewise.
+
+2021-07-09 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * par-ch6.adb (Contains_Import_Aspect): New function.
+ (P_Subprogram): Acknowledge `Import` aspects.
+
+2021-07-09 Bob Duff <duff@adacore.com>
+
+ * exp_put_image.adb (Make_Component_Attributes): Use
+ Implementation_Base_Type to get the parent type. Otherwise,
+ Parent_Type_Decl is actually an internally generated subtype
+ declaration, so we blow up on
+ Type_Definition (Parent_Type_Decl).
+
+2021-07-09 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * gsocket.h: Include net/if.h to get IF_NAMESIZE constant.
+ * s-oscons-tmplt.c: Define IPV6_FLOWINFO for Linux.
+
+2021-07-09 Steve Baird <baird@adacore.com>
+
+ * libgnat/a-cdlili.adb: Reimplement
+ Ada.Containers.Doubly_Linked_Lists.Generic_Sorting.Sort using
+ Mergesort instead of the previous Quicksort variant.
+
+2021-07-09 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch6.adb (Is_Build_In_Place_Function_Call): Add check to
+ verify the Selector_Name of Exp_Node has been analyzed before
+ obtaining its entity.
+
+2021-07-09 Gary Dismukes <dismukes@adacore.com>
+
+ * libgnarl/s-osinte__vxworks.ads: Fix typo ("release" =>
+ "releases") plus comment reformatting.
+ * libgnat/s-os_lib.ads: In a comment, fix typo ("indended" =>
+ "intended"), add a hyphen and semicolon, plus reformatting. In
+ comment for subtype time_t, fix typo ("effect" => "affect"), add
+ hyphens, plus reformatting.
+ * libgnat/s-parame.ads, libgnat/s-parame__ae653.ads,
+ libgnat/s-parame__hpux.ads: Remove period from one-line comment.
+
+2021-07-09 Steve Baird <baird@adacore.com>
+
+ * exp_ch5.adb (Expand_General_Case_Statement): Add new function
+ Else_Statements to handle the case of invalid data analogously
+ to how it is handled when casing on a discrete value.
+ * sem_case.adb (Has_Static_Discriminant_Constraint): A new
+ Boolean-valued function.
+ (Composite_Case_Ops.Scalar_Part_Count): Include discriminants
+ when traversing components.
+ (Composite_Case_Ops.Choice_Analysis.Traverse_Discrete_Parts):
+ Include discriminants when traversing components; the component
+ range for a constrained discriminant is a single value.
+ (Composite_Case_Ops.Choice_Analysis.Parse_Choice): Eliminate
+ Done variable and modify how Next_Part is computed so that it is
+ always correct (as opposed to being incorrect when Done is
+ True). This includes changes in Update_Result (a local
+ procedure). Add new local procedure
+ Update_Result_For_Box_Component and call it not just for box
+ components but also for "missing" components (components
+ associated with an inactive variant).
+ (Check_Choices.Check_Composite_Case_Selector.Check_Component_Subtype):
+ Instead of disallowing all discriminated component types, allow
+ those that are unconstrained or statically constrained. Check
+ discriminant subtypes along with other component subtypes.
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Update
+ documentation to reflect current implementation status.
+ * gnat_rm.texi: Regenerate.
+
+2021-07-09 Justin Squirek <squirek@adacore.com>
+
+ * sem_ch6.adb (Check_Pragma_Inline): Correctly use
+ Corresponding_Spec_Of_Stub when dealing subprogram body stubs.
+
+2021-07-09 Doug Rupp <rupp@adacore.com>
+
+ * Makefile.rtl: Add translations for s-parame__posix2008.ads
+ * libgnarl/s-linux.ads: Import System.Parameters.
+ (time_t): Declare using System.Parameters.time_t_bits.
+ * libgnarl/s-linux__alpha.ads: Likewise.
+ * libgnarl/s-linux__android.ads: Likewise.
+ * libgnarl/s-linux__hppa.ads: Likewise.
+ * libgnarl/s-linux__mips.ads: Likewise.
+ * libgnarl/s-linux__riscv.ads: Likewise.
+ * libgnarl/s-linux__sparc.ads: Likewise.
+ * libgnarl/s-linux__x32.ads: Likewise.
+ * libgnarl/s-qnx.ads: Likewise.
+ * libgnarl/s-osinte__aix.ads: Likewise.
+ * libgnarl/s-osinte__android.ads: Likewise.
+ * libgnarl/s-osinte__darwin.ads: Likewise.
+ * libgnarl/s-osinte__dragonfly.ads: Likewise.
+ * libgnarl/s-osinte__freebsd.ads: Likewise.
+ * libgnarl/s-osinte__gnu.ads: Likewise.
+ * libgnarl/s-osinte__hpux-dce.ads: Likewise.
+ * libgnarl/s-osinte__hpux.ads: Likewise.
+ * libgnarl/s-osinte__kfreebsd-gnu.ads: Likewise.
+ * libgnarl/s-osinte__lynxos178e.ads: Likewise.
+ * libgnarl/s-osinte__qnx.ads: Likewise.
+ * libgnarl/s-osinte__rtems.ads: Likewise.
+ * libgnarl/s-osinte__solaris.ads: Likewise.
+ * libgnarl/s-osinte__vxworks.ads: Likewise.
+ * libgnat/g-sothco.ads: Likewise.
+ * libgnat/s-osprim__darwin.adb: Likewise.
+ * libgnat/s-osprim__posix.adb: Likewise.
+ * libgnat/s-osprim__posix2008.adb: Likewise.
+ * libgnat/s-osprim__rtems.adb: Likewise.
+ * libgnat/s-osprim__x32.adb: Likewise.
+ * libgnarl/s-osinte__linux.ads: use type System.Linux.time_t.
+ * libgnat/s-os_lib.ads (time_t): Declare as subtype of
+ Long_Long_Integer.
+ * libgnat/s-parame.ads (time_t_bits): New constant.
+ * libgnat/s-parame__ae653.ads (time_t_bits): Likewise.
+ * libgnat/s-parame__hpux.ads (time_t_bits): Likewise.
+ * libgnat/s-parame__vxworks.ads (time_t_bits): Likewise.
+ * libgnat/s-parame__posix2008.ads: New file for 64 bit time_t.
+
+2021-07-09 Bob Duff <duff@adacore.com>
+
+ * comperr.adb (Compiler_Abort): Print source file name.
+
+2021-07-09 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-strunb.ads, libgnat/a-strunb__shared.ads: Fix layout
+ in contracts.
+
+2021-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.ads (JSON output format): Document adjusted key name.
+ * repinfo.adb (List_Record_Layout): Use Original_Record_Component
+ if the normalized position of the component is not known.
+ (List_Structural_Record_Layout): Rename Outer_Ent parameter into
+ Ext_End and add Ext_Level parameter. In an extension, if the parent
+ subtype has static discriminants, call List_Record_Layout on it.
+ Output "parent_" prefixes before "variant" according to Ext_Level.
+ Adjust recursive calls throughout the procedure.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.ads (Map_Types): Fix typo.
+
+2021-07-09 Fedor Rybin <frybin@adacore.com>
+
+ * krunch.adb: Add safeguards against index range violations.
+
+2021-07-09 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-strfix.adb: Take advantage of extended returns.
+
+2021-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst
+ (Scalar_Storage_Order): Add paragraph about representation
+ changes.
+ * gnat_rm.texi: Regenerate.
+
+2021-07-09 Frederic Konrad <konrad@adacore.com>
+
+ * Makefile.rtl (LIBGNAT_TARGET_PAIRS) <aarch64*-*-rtems*>: Use
+ the wraplf variant of Aux_Long_Long_Float.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Initialize Orig_N
+ and Typ variables.
+
+2021-07-09 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch13.adb (Resolve_Aspect_Expressions): Use the same
+ processing for Predicate, Static_Predicate and
+ Dynamic_Predicate. Do not build the predicate function spec.
+ Update comments.
+ (Resolve_Name): Only reset Entity when necessary to avoid
+ spurious visibility errors.
+ (Check_Aspect_At_End_Of_Declarations): Handle consistently all
+ Predicate aspects.
+ * sem_ch3.adb (Analyze_Subtype_Declaration): Fix handling of
+ private types with predicates.
+
+2021-07-09 Justin Squirek <squirek@adacore.com>
+
+ * sem_util.ads (Type_Access_Level): Add new optional parameter
+ Assoc_Ent.
+ * sem_util.adb (Accessibility_Level): Treat access discriminants
+ the same as components when the restriction
+ No_Dynamic_Accessibility_Checks is enabled.
+ (Deepest_Type_Access_Level): Remove exception for
+ Debug_Flag_Underscore_B when returning the result of
+ Type_Access_Level in the case where
+ No_Dynamic_Accessibility_Checks is active.
+ (Function_Call_Or_Allocator_Level): Correctly calculate the
+ level of Expr based on its containing subprogram instead of
+ using Current_Subprogram.
+ * sem_res.adb (Valid_Conversion): Add actual for new parameter
+ Assoc_Ent in call to Type_Access_Level, and add test of
+ No_Dynamic_Accessibility_Checks_Enabled to ensure that static
+ accessibility checks are performed for all anonymous access type
+ conversions.
+
+2021-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dbug.ads: Update documentation of various items.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Reorder code.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Reorder code.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Add variable to
+ avoid repeated calls to Etype.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Fix comment.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Use Orig_N variable
+ instead of repeated calls to Original_Node.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): Change types local
+ variables from Entity_Id to Node_Id.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Analyze_Expression_Function): A local Expr
+ constant was shadowing a global constant with the same name and
+ the same value.
+
+2021-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_res.adb (Preanalyze_And_Resolve): Only call
+ Set_Must_Not_Freeze when it is necessary to restore the previous
+ value.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch5.adb (Analyze_Assignment): Clear Current_Assignment at
+ exit.
+ (Analyze_Target_Name): Prevent AST climbing from going too far.
+
+2021-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch5.adb (Analyze_Target_Name): Properly reject a
+ Target_Name when it appears outside of an assignment statement,
+ or within the left-hand side of one.
+
+2021-07-08 Bob Duff <duff@adacore.com>
+
+ * einfo-utils.ads, einfo-utils.adb (Unknown_Alignment,
+ Unknown_Component_Bit_Offset, Unknown_Component_Size,
+ Unknown_Esize, Unknown_Normalized_First_Bit,
+ Unknown_Normalized_Position, Unknown_Normalized_Position_Max,
+ Unknown_RM_Size): Remove these functions.
+ * exp_pakd.adb, exp_util.adb, fe.h, freeze.adb, layout.adb,
+ repinfo.adb, sem_ch13.adb, sem_ch3.adb, sem_util.adb: Remove
+ calls to these functions; do "not Known_..." instead.
+ * gcc-interface/decl.c, gcc-interface/trans.c
+ (Unknown_Alignment, Unknown_Component_Size, Unknown_Esize,
+ Unknown_RM_Size): Remove calls to these functions; do
+ "!Known_..." instead.
+
+2021-07-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dbug.adb (Get_Encoded_Name): Do not encode names of discrete
+ types with custom bounds, except with -fgnat-encodings=all.
+ * exp_pakd.adb (Create_Packed_Array_Impl_Type): Adjust comment.
+
+2021-07-08 Bob Duff <duff@adacore.com>
+
+ * comperr.adb (Compiler_Abort): Call Sinput.Unlock, because if
+ this is called late, then Source_Dump would crash otherwise.
+ * debug.adb: Correct documentation of the -gnatd.9 switch.
+ * exp_ch4.adb (Expand_Allocator_Expression): Add a comment.
+ * exp_ch6.adb: Minor comment fixes. Add assertion.
+ * exp_ch6.ads (Is_Build_In_Place_Result_Type): Correct comment.
+ * exp_ch7.adb, checks.ads: Minor comment fixes.
+
+2021-07-08 Doug Rupp <rupp@adacore.com>
+
+ * sigtramp-vxworks-target.inc: Rename to...
+ * sigtramp-vxworks-target.h: ... this.
+ * sigtramp-vxworks.c, Makefile.rtl: Likewise.
+
+2021-07-08 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * lib-writ.ads: Mention SCOs dependency as reason for duplicates.
+ * lib.ads (Units): Update documentation to mention duplicated
+ units.
+
+2021-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * style.adb (Missing_Overriding): Do not emit message when
+ parent of subprogram is a full type declaration.
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * par-ch5.adb (P_Iterator_Specification): Add support for access
+ definition in loop parameter.
+ * sem_ch5.adb (Check_Subtype_Indication): Renamed...
+ (Check_Subtype_Definition): ... into this and check for conformance
+ on access definitions, and improve error messages.
+ (Analyze_Iterator_Specification): Add support for access definition
+ in loop parameter.
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_util.ads, sem_util.adb
+ (Apply_Compile_Time_Constraint_Error): New parameter
+ Emit_Message.
+ * sem_ch4.adb (Analyze_Selected_Component): Disable warning
+ within an instance.
+
+2021-07-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_imgv.adb: Add with and use clause for Restrict and Rident.
+ (Build_Enumeration_Image_Tables): Do not generate the hash function
+ if the No_Implicit_Loops restriction is active.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb, sem_ch6.adb, sem_ch9.adb, sprint.adb: Simplify
+ checks for non-empty lists.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * par-ch10.adb (Unit_Display): Remove redundant condition; fix
+ whitespace.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-load.adb (Load): Replace early return with goto to properly
+ restore context on failure.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb (Ensure_System_Dependency): Simplify condition.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-load.adb (Load_Unit): Fix style in comment.
+ * par-load.adb (Load): Likewise.
+ * scng.adb (Initialize_Scanner): Fix whitespace.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * par-load.adb (Load): Don't remove unit, but flag it as
+ erroneous and return.
+
+2021-07-08 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * exp_prag.adb (Expand_Pragma_Inspection_Point): Fix error
+ message.
+
+2021-07-08 Yannick Moy <moy@adacore.com>
+
+ * layout.adb (Layout_Type): Do not call Number_Dimensions if the
+ type does not have First_Index set.
+
+2021-07-08 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * exp_prag.adb (Expand_Pragma_Inspection_Point): After expansion
+ of the Inspection_Point pragma, check if referenced entities
+ that have a freeze node are already frozen. If they aren't, emit
+ a warning and turn the pragma into a no-op.
+
+2021-07-08 Yannick Moy <moy@adacore.com>
+
+ * layout.adb (Layout_Type): Add guard before calling Expr_Value.
+
+2021-07-08 Yannick Moy <moy@adacore.com>
+
+ * layout.adb (Layout_Type): Special case when RM_Size and Esize
+ can be computed for packed arrays.
+
+2021-07-08 Steve Baird <baird@adacore.com>
+
+ * rtsfind.ads, rtsfind.adb: Add support for finding the packages
+ System.Atomic_Operations and
+ System.Atomic_Operations.Test_And_Set and the declarations
+ within that latter package of the type Test_And_Set_Flag and the
+ function Atomic_Test_And_Set.
+ * exp_ch11.adb (Expand_N_Exception_Declaration): If an exception
+ is declared other than at library level, then we need to call
+ Register_Exception the first time (and only the first time) the
+ declaration is elaborated. In order to decide whether to
+ perform this call for a given elaboration of the declaration, we
+ used to unconditionally use a (library-level) Boolean variable.
+ Now we instead use a variable of type
+ System.Atomic_Operations.Test_And_Set.Test_And_Set_Flag unless
+ either that type is unavailable or a No_Tasking restriction is
+ in effect (in which case we use a Boolean variable as before).
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/system.ads: Add No_Tasking restriction.
+
+2021-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * libgnat/a-cohama.ads: Introduce an equality operator over
+ cursors.
+ * libgnat/a-cohase.ads: Ditto.
+ * libgnat/a-cohama.adb: Add body for "=" over cursors.
+ (Insert): Do not set the Position component of the cursor that
+ denotes the inserted element.
+ * libgnat/a-cohase.adb: Ditto.
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-cbdlli.adb, libgnat/a-cbhama.adb,
+ libgnat/a-cbhase.adb, libgnat/a-cbmutr.adb,
+ libgnat/a-cborma.adb, libgnat/a-cborse.adb,
+ libgnat/a-cobove.adb, libgnat/a-textio.adb,
+ libgnat/a-witeio.adb, libgnat/a-ztexio.adb: Make code compatible
+ with No_Dynamic_Accessibility_Checks restriction.
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * debug.adb, sem_util.adb: Revert meaning of -gnatd_b.
+ * sem_res.adb: Minor reformatting.
+
+2021-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * make.adb, osint.adb: Make code compatible with
+ No_Dynamic_Accessibility_Checks restriction.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb (Ensure_System_Dependency): Replace search in
+ Lib.Units with a search in Lib.Unit_Names.
+
+2021-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sinput-l.adb (Load_File): Simplify foreword manipulation with
+ concatenation; similar for filename with preprocessed output.
+
+2021-07-07 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * s-oscons-tmplt.c (MSG_WAITALL): Remove wrong #ifdef
+ __MINWGW32__.
+
+2021-07-07 Gary Dismukes <dismukes@adacore.com>
+
+ * einfo-utils.adb (Primitive_Operations): Default to returning
+ Direct_Primitive_Operations in the case of concurrent types
+ (when Corresponding_Record_Type not present).
+ * sem_ch9.adb (Analyze_Protected_Type_Declaration): Initialize
+ Direct_Primitive_Operations to an empty element list.
+ (Analyze_Task_Type_Declaration): Initialize
+ Direct_Primitive_Operations to an empty element list.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_eval.adb (Set_Checking_Potentially_Static_Expression):
+ Stronger assertion.
+
+2021-07-07 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch12.adb (Analyze_Subprogram_Instantiation): Mark Anon_Id
+ intrinsic before calling Analyze_Instance_And_Renamings because
+ this flag may be propagated to other nodes.
+
+2021-07-07 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * s-oscons-tmplt.c (TCP_KEEPCNT TCP_KEEPIDLE, TCP_KEEPINTVL):
+ Hardcode on Windows if undefined.
+
+2021-07-07 Bob Duff <duff@adacore.com>
+
+ * checks.adb (Install_Primitive_Elaboration_Check): Do not
+ generate elaboration checks for primitives if pragma Pure or
+ Preelaborate is present. Misc comment fixes, including
+ referring to the correct kind of check (elaboration, not
+ accessibility).
+ * checks.ads, restrict.adb, sem_cat.ads, sinfo.ads: Minor
+ reformatting and comment fixes.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Simplify processing of pragma
+ CPP_Constructor.
+
+2021-07-07 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/g-debpoo.adb (Code_Address_For_Allocate_End): Default
+ Initialize.
+
+2021-07-07 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/s-atocou.ads, libgnat/s-atocou__builtin.adb: Code
+ cleanups.
+
+2021-07-07 Gary Dismukes <dismukes@adacore.com>
+
+ * freeze.adb (Check_Inherited_Conditions): Setting of Ekind,
+ LSP_Subprogram, and Is_Wrapper needs to happen for null
+ procedures as well as other wrapper cases, so the code is moved
+ from the else part in front of the if statement. (Fixes a
+ latent bug encountered while working on this set of changes.)
+ * sem_attr.adb (Resolve_Attribute): Report an error for the case
+ of an Access attribute applied to a primitive of an abstract
+ type when the primitive has any nonstatic Pre'Class or
+ Post'Class expressions.
+ * sem_ch8.adb (Analyze_Subprogram_Renaming): Report an error for
+ the case of a actual subprogram associated with a nonabstract
+ formal subprogram when the actual is a primitive of an abstract
+ type and the primitive has any nonstatic Pre'Class or Post'Class
+ expressions.
+ * sem_disp.adb (Check_Dispatching_Context): Remove special
+ testing for null procedures, and replace it with a relaxed test
+ that avoids getting an error about illegal calls to abstract
+ subprograms in cases where RM 6.1.1(7/5) applies in
+ Pre/Post'Class aspects. Also, remove special test for
+ Postcondition, which seems to be unnecessary, update associated
+ comments, and fix a typo in one comment.
+ (Check_Dispatching_Call): Remove an unneeded return statement,
+ and report an error for the case of a nondispatching call to a
+ nonabstract subprogram of an abstract type where the subprogram
+ has nonstatic Pre/Post'Class aspects.
+ * sem_util.ads
+ (Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post): New function.
+ (In_Pre_Post_Condition): Add a flag formal Class_Wide_Only,
+ defaulted to False, for indicating whether the function should
+ only test for the node being within class-wide pre- and
+ postconditions.
+ * sem_util.adb
+ (Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post): New function
+ to determine whether a subprogram is a primitive of an abstract
+ type where the primitive has class-wide Pre/Post'Class aspects
+ specified with nonstatic expressions.
+ (In_Pre_Post_Condition): Extend testing to account for the new
+ formal Class_Wide_Only.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Check_Shared_Variable_Control_Aspects): Errors
+ emitted via Check_Volatility_Compatibility are now emitted at
+ Actual, just like other errors emitted by
+ Check_Shared_Variable_Control_Aspects.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * uname.adb (Get_Unit_Name): Simplify with a bounded string
+ buffer; also, this addresses a ??? comment about the max length
+ being exceeded.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * uname.adb (Get_Body_Name, Get_Parent_Body_Name,
+ Get_Parent_Spec_Name, Get_Spec_Name, Is_Child_Name,
+ Is_Body_Name, Is_Spec_Name, Name_To_Unit_Name): Use a local
+ instead of the global buffer.
+
+2021-07-07 Bob Duff <duff@adacore.com>
+
+ * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Combine
+ processing of Size and Value_Size clauses. Ensure that
+ Value_Size is treated the same as Size, in the cases where both
+ are allowed (i.e. the prefix denotes a first subtype). Misc
+ cleanup.
+ * einfo-utils.adb (Init_Size): Add assertions.
+ (Size_Clause): Return a Value_Size clause if present, instead of
+ just looking for a Size clause.
+ * einfo.ads (Has_Size_Clause, Size_Clause): Change documentation
+ to include Value_Size.
+ * sem_ch13.ads, layout.ads, layout.adb: Comment modifications.
+
+2021-07-07 Steve Baird <baird@adacore.com>
+
+ * exp_dist.adb (Add_RACW_Primitive_Declarations_And_Bodies): Add
+ TSS_Put_Image to list of predefined primitives that need special
+ treatment.
+ (Build_General_Calling_Stubs, Build_Subprogram_Receiving_Stubs):
+ Remove previous hack for dealing with TSS_Put_Image procedures.
+
+2021-07-07 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.adb (Get_Socket_Option): Add 500ms only when
+ Minus_500ms_Windows_Timeout is True.
+ (Set_Socket_Option): Use "* 1000" instead of "/ 0.001" to
+ convert to milliseconds.
+
+2021-07-07 Bob Duff <duff@adacore.com>
+
+ * tbuild.adb (Unchecked_Convert_To): Set the Parent of the new
+ node to the Parent of the old node.
+ * tbuild.ads (Unchecked_Convert_To): Document differences
+ between Convert_To and Unchecked_Convert_To. The previous
+ documentation claimed they are identical except for the
+ uncheckedness of the conversion.
+
+2021-07-07 Yannick Moy <moy@adacore.com>
+
+ * checks.adb (Apply_Scalar_Range_Check): Remove special case for
+ GNATprove mode.
+ * sem_res.adb (Resolve_Arithmetic_Op): Same.
+ * sem_util.adb (Apply_Compile_Time_Constraint_Error): Same.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Check_For_Primitive_Subprogram): Move
+ declarations of local variables after nested subprogram bodies.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_disp.adb (CPP_Num_Prims): Reuse List_Length.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch3.adb, exp_ch6.adb, sem_ch6.adb: Replace Ekind
+ membership test in Private_Kind with a call to Is_Private_Type.
+
+2021-07-07 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen-gen_entities.adb: Remove Linker_Section_Pragma
+ field from Record_Field_Kind. Minor comment improvement.
+
+2021-07-07 Yannick Moy <moy@adacore.com>
+
+ * libgnat/a-ngelfu.ads (Cot): Fix precondition.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * par.adb (Par): A local Name variable is now a renaming of a
+ constant slice.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * gnat1drv.adb (Gnat1drv): Remove flagging of main unit and its
+ corresponding spec as requiring code generation; now the flags
+ are set much earlier.
+ * lib-load.adb (Load_Main_Source): Set Generate_Code flag on the
+ main unit source.
+ (Make_Instance_Unit): Copy Generate_Code flag from the main unit
+ to instance units.
+ * lib-writ.adb (Write_ALI): Remove redundant condition;
+ Generate_Code flag is always set for the main unit.
+ * par-load.adb (Load): Set Generate_Code flag on the main unit's
+ corresponding spec, if any.
+
+2021-07-07 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.ads (Option_Name): Add Keep_Alive_Count,
+ Keep_Alive_Idle, and Keep_Alive_Interval items to enumeration.
+ (Option_Type): Add Keep_Alive_Count, Keep_Alive_Idle, and
+ Keep_Alive_Interval alternatives to the case of discriminated
+ record.
+ * libgnat/g-socket.adb (Options): Add Keep_Alive_Count,
+ Keep_Alive_Idle, and Keep_Alive_Interval to items enumerator to
+ OS constant converter.
+ (Set_Socket_Option): Process Keep_Alive_Count, Keep_Alive_Idle,
+ and Keep_Alive_Interval socket options.
+ (Get_Socket_Option): Idem.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb (Write_ALI): Exit from loop after seeing first
+ unit that violates No_Elaboration_Code restriction.
+
+2021-07-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * inline.adb (Instantiate_Bodies): Fix white in declaration.
+ (Remove_Dead_Instance): Change iteration from WHILE to FOR.
+
+2021-07-07 Bob Duff <duff@adacore.com>
+
+ * checks.adb, exp_attr.adb, exp_ch4.adb, exp_ch6.adb,
+ exp_ch9.adb, exp_disp.adb, exp_util.adb, inline.adb,
+ sem_res.adb: Change all calls to Make_Unchecked_Type_Conversion
+ to call Unchecked_Convert_To instead. This involves removing
+ New_Occurrence_Of on the first parameter, because
+ Unchecked_Convert_To expects a type entity, rather than the name
+ of one. Also, removed calls to Relocate_Node, because
+ Unchecked_Convert_To takes care of that.
+ * sinfo.ads: Change comment to be worded more firmly.
+
+2021-07-07 Steve Baird <baird@adacore.com>
+
+ * libgnarl/s-tassta.adb (Free_Task): Acquire the Task_Lock
+ before, rather than after, querying the task's Terminated flag.
+ Add a corresponding Task_Unlock call.
+
+2021-07-06 Bob Duff <duff@adacore.com>
+
+ * atree.ads (Current_Error_Node): Initialize to Empty.
+
+2021-07-06 Steve Baird <baird@adacore.com>
+
+ * exp_put_image.adb: Eliminate references to
+ Debug_Flag_Underscore_Z. Change the meaning of the function
+ Enable_Put_Image. Previously, a result of False for a tagged
+ type would mean that the type does not get a Put_Image (PI)
+ routine at all. Now, it means that the type gets a PI routine
+ with very abbreviated functionality (just a call to
+ Unknown_Put_Image). This resolves problems in mixing code
+ compiled with and without the -gnat2022 switch.
+ * exp_ch3.adb: Enable_Put_Image no longer participates in
+ determining whether a tagged type gets a Put_Image procedure. A
+ tagged type does not get a Put_Image procedure if the type
+ Root_Buffer_Type is unavailable. This is needed to support cross
+ targets where tagged types are supported but the type
+ Root_Buffer_Type is not available.
+ * exp_dist.adb: Add workarounds for some problems that arise
+ when using the (obsolete?) Garlic implementation of the
+ distributed systems annex with Ada 2022 constructs.
+ * libgnat/a-sttebu.ads: Workaround a bootstrapping problem.
+ Older compilers do not support raise expressions, so revise the
+ the Pre'Class condition to meet this requirement without
+ changing the condition's behavior at run time.
+
+2021-07-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo-input.adb (JSON_Entity_Kind, Read_Variant_Part): Fix
+ typo in comment.
+
+2021-07-06 Steve Baird <baird@adacore.com>
+
+ * sem_ch5.adb (Analyze_Assignment): Add new nested function,
+ Omit_Range_Check_For_Streaming, and make call to
+ Apply_Scalar_Range_Check conditional on the result of this new
+ function.
+ * exp_attr.adb (Compile_Stream_Body_In_Scope): Eliminate Check
+ parameter, update callers. The new
+ Omit_Range_Check_For_Streaming parameter takes the place of the
+ old use of calling Insert_Action with Suppress => All_Checks,
+ which was insufficiently precise (it did not allow suppressing
+ checks for one component but not for another).
+ (Expand_N_Attribute_Reference): Eliminate another "Suppress =>
+ All_Checks" from an Insert_Action call, this one in generating
+ the expansion of a T'Read attribute reference for a composite
+ type T.
+
+2021-07-06 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_ch5.adb (Analyze_Loop_Parameter_Specification): Check for
+ empty loops caused by constraints.
+
+2021-07-06 Nicolas Roche <roche@adacore.com>
+
+ * rtinit.c (skip_quoted_string): Handle malformed command line
+ with no closing double quote.
+ (skip_argument): Handle case in which a null character is
+ encountered by skip_quote_string.
+
+2021-07-06 Piotr Trojanek <trojanek@adacore.com>
+
+ * uname.adb (Add_Node_Name): Replace local constant whose
+ initial expression was evaluated even when unnecessary with just
+ that expression that is evaluated at most once and only when
+ needed.
+
+2021-07-06 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib.adb (Remove_Unit): Replace defensive code with an
+ assertion.
+ * par-load.adb (Load): Address a question mark in the comment.
+
+2021-07-06 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Enclosing_Comp_Unit_Node): When the loop exits
+ the Current_Node is either an N_Compilation_Unit node or Empty,
+ so simply return it without redundant checks.
+
+2021-07-06 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-load.adb (Load_Unit): Remove excessive whitespace.
+ * lib.adb (Is_Internal_Unit, Is_Predefined_Unit): Likewise.
+ * par-ch10.adb (P_Compilation_Unit): Simplify with membership
+ test.
+ * par-load.adb (Load): Likewise.
+ * uname.adb (Get_Unit_Name): Likewise.
+
+2021-07-06 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb (Ensure_System_Dependency): Simplify by reusing a
+ constant name.
+
+2021-07-06 Steve Baird <baird@adacore.com>
+
+ * exp_ch5.adb
+ (Expand_N_Case_Statement.Expand_General_Case_Statement.Pattern_Match):
+ When generating an equality test for a statically known discrete
+ value, only generate the numeric value if the discrete type is
+ not an enumeration type. If it is an enumeration type, then
+ call Get_Enum_Lit_From_Pos instead.
+
+2021-07-06 Justin Squirek <squirek@adacore.com>
+
+ * par-ch6.adb (Get_Return_Kind): Removed.
+ (Is_Extended): Created to identify simple and "when" return
+ statements from extended return statements.
+ (P_Return_Statement): Merged simple and "when" return statement
+ processing.
+
+2021-07-06 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch4.adb (Try_One_Prefix_Interpretation): Augment test of
+ "not Extensions_Allowed" with test for absence of Obj_Type's
+ primitive operations Elist, as an additional condition for early
+ return from this procedure.
+
+2021-07-06 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch4.adb (Process_Transient_In_Expression): In one comment,
+ fix two typos and reorder wording of one sentence, plus minor
+ reformatting.
+
+2021-07-06 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch5.adb (Expand_Formal_Container_Element_Loop): Remove
+ legacy expansion of element iterators, and use expansion form
+ used by unconstrained element types in the general case.
+
+2021-07-06 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Process_Transient_In_Expression): Ensure that
+ Fin_Context, used to insert finalization code for the
+ expression, is a list member: the value returned by
+ Find_Hook_Context may be an expression node when the transient
+ is part of a larger expression and it has a non-boolean type.
+
+2021-07-06 Yannick Moy <moy@adacore.com>
+
+ * sem_case.adb: Fix error message.
+
+2021-07-06 Bob Duff <duff@adacore.com>
+
+ * tbuild.adb (Convert_To): Add assert, along with a comment.
+ (Make_DT_Access): Remove this function, which is not used. It
+ was incorrect anyway (the call to New_Occurrence_Of should not
+ be there).
+ (Unchecked_Convert_To): Add assert. The previous version's test
+ for unchecked conversion to the same type was redundant and
+ could never be true, because the previous 'if' already checked
+ for ANY expression of the same type. Remove that, and replace
+ with a test for unchecked conversion to a related type.
+ Otherwise, we somethings get things like
+ "finalize(some_type!(some_type!(x)))" in the generated code,
+ where x is already of type some_type, but we're converting it to
+ the private type and then to the full type or vice versa (so the
+ types aren't equal, so the previous 'if' doesn't catch it).
+ Avoid updating the Parent. This is not necessary; the Parent
+ will be updated if/when the node is attached to the tree.
+ * tbuild.ads: Fix comments. No need to say "this is safe" when
+ we just explained that a few lines earlier. Remove
+ Make_DT_Access.
+ * sinfo.ads: Add comments.
+ * exp_ch7.adb (Make_Finalize_Address_Stmts): Minor comment fix.
+ * gen_il-gen.adb, gen_il-gen.ads, gen_il-gen-gen_nodes.adb,
+ gen_il-internals.ads: Implement a feature where you can put:
+ Nmake_Assert => "expr" where expr is a boolean expression in a
+ call to Create_Concrete_Node_Type. It is added in a pragma
+ Assert in the Nmake.Make_... function for that type.
+
+2021-07-06 Gary Dismukes <dismukes@adacore.com>
+
+ * checks.adb: Remove calls of Set_Do_Tag_Check (N, False).
+ * einfo.ads: Remove hanging unneeded ??? comment ("this real description
+ was clobbered").
+ * exp_util.ads (Insert_Actions_After): Remove ??? from spec comment.
+ * gen_il-fields.ads (Opt_Field_Enum): Remove literals
+ Do_Accessibility_Check and Do_Tag_Check.
+ * gen_il-gen-gen_nodes.adb: Remove all calls to Sm for
+ Do_Accessibility_Check and Do_Tag_Check.
+ * sem_type.ads (Is_Subtype_Of): Remove obsolete ???
+ comment (function is not limited to scalar subtypes).
+ * sem_util.ads (Is_Local_Variable_Reference): Revise comment to
+ mention out-mode parameters as well, and remove ???.
+ (Propagate_Concurrent_Flags): Minor reformatting.
+ (Propagate_Invariant_Attributes): Typo fix.
+ (Propagate_Predicate_Attributes): Indicate what is propagated
+ and remove ??? comment.
+ * sem_util.adb (Cannot_Raise_Constraint_Error): Remove unneeded
+ test of Do_Tag_Check.
+ (Is_Local_Variable_Reference): Extend function to testing for
+ formals of mode out as well.
+ * sinfo.ads: Remove ??? comment about flag
+ Convert_To_Return_False indicating that the flag is obsolete (in
+ fact it's used). Remove references to Do_Accessibility_Check and
+ Do_Tag_Check (and the two associated ??? comments), as these
+ flags are unneeded.
+ * sinfo-cn.adb (Change_Conversion_To_Unchecked): Remove call of
+ Set_Do_Tag_Check (N, False).
+ * targparm.ads (Support_Atomic_Primitives_On_Target): Remove ???
+ comment, plus minor reformatting.
+
+2021-07-06 Justin Squirek <squirek@adacore.com>
+
+ * par-ch6.adb (Get_Return_Kind): Properly handle the case of a
+ "return when" statement in the procedure case.
+
+2021-07-06 Bob Duff <duff@adacore.com>
+
+ * sem.ads (Node_To_Be_Wrapped): Minor comment fix.
+ * exp_ch7.adb (Establish_Transient_Scope): Misc cleanups and
+ comment improvements.
+ (Set_Node_To_Be_Wrapped): Remove -- not worth putting this code
+ in a separate procedure, called only once.
+ * sem_util.adb (Requires_Transient_Scope): Assert that our
+ parameter has the right Kind. It probably shouldn't be E_Void,
+ but that is passed in in some cases.
+ (Ensure_Minimum_Decoration): Move the call later, so we know Typ
+ is Present, and remove "if Present (Typ)" from this procedure.
+ * exp_aggr.adb (Convert_To_Assignments): Use membership test,
+ and avoid the "if False" idiom.
+ (Expand_Array_Aggregate): Remove a ??? comment.
+ * sem_ch8.adb (Push_Scope): Take advantage of the full coverage
+ rules for aggregates.
+ * sem_res.adb (Resolve_Declare_Expression): Remove test for
+ Is_Type -- that's all it can be. Use named notation in call to
+ Establish_Transient_Scope.
+ * libgnat/a-cdlili.adb (Adjust): Remove redundant code.
+ (Clear): Remove "pragma Warnings (Off);", which wasn't actually
+ suppressing any warnings.
+
+2021-07-06 Bob Duff <duff@adacore.com>
+
+ * gen_il-gen-gen_nodes.adb: Change the parent of
+ N_Exception_Declaration to be N_Declaration. Minor comment fix.
+
+2021-07-06 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Type_Conversion): If the conversion is
+ the name of an assignment operation do not apply predicate check
+ to it prior to the assignment.
+
+2021-07-06 Bob Duff <duff@adacore.com>
+
+ * libgnat/a-conhel.adb: Assert that tampering counts remain
+ between 0 and 2**31-1. This makes debugging of
+ finalization-related bugs easier.
+
+2021-07-06 Doug Rupp <rupp@adacore.com>
+
+ * Makefile.rtl (LIBGNAT_TARGET_PAIRS): Use s-osprim__posix.adb
+ vice s-osprim__vxworks.adb for all vxworks7r2 targets.
+
+2021-07-06 Richard Kenner <kenner@adacore.com>
+
+ * gen_il-types.ads (Void_Or_Type_Kind,
+ Exception_Or_Object_Kind): Declare.
+ * gen_il-gen-gen_entities.adb: Likewise.
+
+2021-07-06 Gary Dismukes <dismukes@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Add a
+ description of the feature of prefixed-view calls for untagged
+ types to the section on pragma Extensions_Allowed.
+ * gnat_rm.texi: Regenerate.
+ * einfo.ads: Update specification for
+ Direct_Primitive_Operations to reflect its use for untagged
+ types when Extensions_Allowed is True.
+ * gen_il-gen-gen_entities.adb: Allow Direct_Primitive_Operations
+ as a field of untagged classes of types by removing the "Pre"
+ test of "Is_Tagged_Type (N)", and making that field generally
+ available for all types and subtypes by defining it for
+ Type_Kind and removing its specification for individual classes
+ of types.
+ * sem_ch3.adb (Analyze_Full_Type_Declaration): Initialize the
+ Direct_Primitive_Operations list when not already set for the
+ new (sub)type and its base type (except when Ekind of the type
+ is E_Void, which can happen due to errors in cases where
+ Derived_Type_Declaration is called and perhaps in other
+ situations).
+ (Analyze_Subtype_Declaration): Inherit
+ Direct_Primitive_Operations list from the base type, for record
+ and private cases.
+ (Build_Derived_Record_Type): Initialize the
+ Direct_Primitive_Operations list for derived record and private
+ types.
+ (Build_Derived_Type): Initialize the Direct_Primitive_Operations
+ list for derived types (and also for their associated base types
+ when needed).
+ (Process_Full_View): For full types that are untagged record and
+ private types, copy the primitive operations of the partial view
+ to the primitives list of the full view.
+ * sem_ch4.adb (Analyze_Selected_Component): Allow prefixed
+ notation for subprogram calls in the case of untagged
+ types (when Extensions_Allowed is True). In the case where
+ Is_Private_Type (Prefix_Type) is True, call Try_Object_Operation
+ when a discriminant selector wasn't found. Also call
+ Try_Object_Operation in other type kind cases (when
+ Extensions_Allowed is True).
+ (Try_Object_Operation.Try_One_Prefixed_Interpretation): Prevent
+ early return in the untagged case (when Extensions_Allowed is
+ True). Condition main call to Try_Primitive_Operation on the
+ type having primitives, and after that, if Prim_Result is False,
+ test for case where the prefix type is a named access type with
+ primitive operations and in that case call
+ Try_Primitive_Operation after temporarily resetting Obj_Type to
+ denote the access type (and restore it to the designated type
+ after the call)
+ (Try_Object_Operation.Valid_First_Argument_Of): Do matching type
+ comparison by testing Base_Type (Obj_Type) against
+ Base_Type (Typ), rather than against just Typ, to properly
+ handle cases where the object prefix has a constrained
+ subtype. (Fixes a bug discovered while working on this
+ feature.)
+ * sem_ch6.adb
+ (New_Overloaded_Entity.Check_For_Primitive_Subprogram): Add a
+ primitive of an untagged type to the type's list of primitive
+ operations, for both explicit and implicit (derived, so
+ Comes_From_Source is False) subprogram declarations. In the case
+ where the new primitive overrides an inherited subprogram,
+ locate the primitives Elist that references the overridden
+ subprogram, and replace that element of the list with the new
+ subprogram (done by calling the new procedure
+ Add_Or_Replace_Untagged_Primitive on the result type and each
+ formal atype).
+ (Check_For_Primitive_Subprogram.Add_Or_Replace_Untagged_Primitive):
+ New nested procedure to either add or replace an untagged
+ primitive subprogram in a given type's list of primitive
+ operations (replacement happens in case where the new subprogram
+ overrides a primitive of the type).
+ * sem_ch7.adb (New_Private_Type): When Extensions_Allowed is
+ True, initialize the Direct_Primitive_Operations list of a
+ private type to New_Elmt_List in the case of untagged types.
+ * sem_ch8.adb (Find_Selected_Component): In the case where the
+ prefix is an entity name, relax condition that tests
+ Has_Components so that Analyze_Selected_Component will also be
+ called when Extensions_Allowed is True and the prefix type is
+ any type.
+
+2021-07-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Do not perform
+ conformance check when the subprogram body has been created for
+ an expression function that is not a completion of a previous
+ specification, because the profile of the constructed body is
+ copied from the expression function itself.
+
+2021-07-06 Steve Baird <baird@adacore.com>
+
+ * doc/gnat_rm/implementation_of_specific_ada_features.rst: Add a
+ warning indicating that the details of the default (i.e.,
+ selected by the compiler) implementation of T'Put_Image for a
+ nonscalar type T are subject to change.
+ * gnat_rm.texi: Regenerate.
+
+2021-07-05 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * gnat-style.texi, gnat_rm.texi, gnat_ugn.texi: Regenerate.
+
+2021-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Depends_In_Decl_Part): Reject overlays
+ in Depends and Refined_Depends contracts.
+ (Analyze_Global_In_Decl_Part): Likewise for Global and
+ Refined_Global.
+ (Analyze_Initializes_In_Decl_Part): Likewise for Initializes
+ (when appearing both as a single item and as a initialization
+ clause).
+ * sem_util.ads (Ultimate_Overlaid_Entity): New routine.
+ * sem_util.adb (Report_Unused_Body_States): Ignore overlays.
+ (Ultimate_Overlaid_Entity): New routine.
+
+2021-07-05 Claire Dross <dross@adacore.com>
+
+ * libgnat/a-cfdlli.ads, libgnat/a-cfdlli.adb
+ libgnat/a-cfinve.ads, libgnat/a-cfinve.adb,
+ libgnat/a-cofove.ads, libgnat/a-cofove.adb,
+ libgnat/a-coboho.ads, libgnat/a-coboho.adb (Constant_Reference):
+ Get a read-only access to an element of the container.
+ (At_End): Ghost functions used to express pledges in the
+ postcondition of Reference.
+ (Reference): Get a read-write access to an element of the
+ container.
+ * libgnat/a-cfhama.ads, libgnat/a-cfhama.adb,
+ libgnat/a-cforma.ads, libgnat/a-cforma.adb: The full view of the
+ Map type is no longer a tagged type, but a wrapper over this
+ tagged type. This is to avoid issues with dispatching result in
+ At_End functions.
+ (Constant_Reference): Get a read-only access to an element of
+ the container.
+ (At_End): Ghost functions used to express pledges in the
+ postcondition of Reference.
+ (Reference): Get a read-write access to an element of the
+ container.
+ * libgnat/a-cfhase.ads, libgnat/a-cfhase.adb,
+ libgnat/a-cforse.ads, libgnat/a-cforse.adb: The full view of the
+ Map type is no longer a tagged type, but a wrapper over this
+ tagged type.
+ (Constant_Reference): Get a read-only access to an element of
+ the container.
+ * libgnat/a-cofuse.ads, libgnat/a-cofuve.ads (Copy_Element):
+ Expression function used to cause SPARK to make sure
+ Element_Type is copiable.
+ * libgnat/a-cofuma.ads (Copy_Key): Expression function used to
+ cause SPARK to make sure Key_Type is copiable.
+ (Copy_Element): Expression function used to cause SPARK to make
+ sure Element_Type is copiable.
+
+2021-07-05 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Analyze_Global_Item): Adapt to update SPARK RM
+ rule.
+
+2021-07-05 Arnaud Charlet <charlet@adacore.com>
+
+ * Make-generated.in: Add -f switch to ensure cp will never fail.
+
+2021-07-05 Steve Baird <baird@adacore.com>
+
+ * exp_ch3.adb (Build_Record_Init_Proc.Build_Assignment): When
+ building the assignment statement corresponding to the default
+ expression for a component, we make a copy of the expression.
+ When making that copy (and if we have seen a component that
+ requires late initialization), pass a Map parameter into the
+ call to New_Copy_Tree to redirect references to the type to
+ instead refer to the _Init formal parameter of the init proc.
+ This includes hoisting the declaration of Has_Late_Init_Comp out
+ one level so that it becomes available to Build_Assignment.
+ (Find_Current_Instance): Return True for other kinds of current
+ instance references, instead of just access-valued attribute
+ references such as T'Access.
+ * sem_util.adb (Is_Aliased_View): Return True for the _Init
+ formal parameter of an init procedure. The changes in
+ exp_ch3.adb can have the effect of replacing a "T'Access"
+ attribute reference in an init procedure with an "_Init'Access"
+ attribute reference. We want such an attribute reference to be
+ legal. However, we do not simply mark the formal parameter as
+ being aliased because that might impact callers.
+ (Is_Object_Image): Return True if Is_Current_Instance returns
+ True for the prefix of an Image (or related attribute) attribute
+ reference.
+
+2021-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch3.adb (Stream_Operation_OK): Reuse
+ Is_Concurrent_Interface.
+ * sem_ch3.adb (Analyze_Interface_Declaration,
+ Build_Derived_Record_Type): Likewise.
+ * sem_ch6.adb (Check_Limited_Return): Likewise.
+ * sem_util.adb (Is_Concurrent_Interface): Don't call
+ Is_Interface because each of the Is_Protected_Interface,
+ Is_Synchronized_Interface and Is_Task_Interface calls it anyway.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_ch6.adb (Check_Limited_Return): Replace Comes_From_Source
+ with Comes_From_Extended_Return_Statement.
+
+2021-07-05 Steve Baird <baird@adacore.com>
+
+ * libgnat/a-stobbu.adb, libgnat/a-stobbu.ads,
+ libgnat/a-stobfi.adb, libgnat/a-stobfi.ads,
+ libgnat/a-stoubu.adb, libgnat/a-stoubu.ads,
+ libgnat/a-stoufi.adb, libgnat/a-stoufi.ads,
+ libgnat/a-stoufo.adb, libgnat/a-stoufo.ads,
+ libgnat/a-stouut.adb, libgnat/a-stouut.ads,
+ libgnat/a-stteou.ads: Delete files.
+ * Makefile.rtl, impunit.adb: Remove references to deleted files.
+
+2021-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Has_Compatible_Alignment_Internal): If the
+ prefix of the Address expression is an entire object with a
+ known alignment, then skip checks related to its size.
+
+2021-07-05 Doug Rupp <rupp@adacore.com>
+
+ * libgnat/s-os_lib.ads: Import OS_Time comparison ops as
+ intrinsic.
+ * libgnat/s-os_lib.adb: Remove OS_TIme comparison ops
+ implementation.
+
+2021-07-05 Doug Rupp <rupp@adacore.com>
+
+ * libgnat/s-os_lib.ads: Add some comments about time_t.
+ * libgnat/s-os_lib.adb (GM_Split/To_GM_Time): Rename formal to
+ P_OS_Time.
+ (GM_Time_Of/To_OS_Time): Likewise.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_res.adb (Resolve): Insert minus sign if needed.
+
+2021-07-05 Steve Baird <baird@adacore.com>
+
+ * exp_put_image.adb:
+ (Enable_Put_Image, Preload_Root_Buffer_Type): Revert to querying
+ the -gnatd_z switch, as opposed to testing whether Ada_Version >= Ada_2022.
+
+2021-07-05 Justin Squirek <squirek@adacore.com>
+
+ * checks.adb (Accessibility_Checks_Suppressed): Add check
+ against restriction No_Dynamic_Accessibility_Checks.
+ (Apply_Accessibility_Check): Add assertion to check restriction
+ No_Dynamic_Accessibility_Checks is not active.
+ * debug.adb: Add documentation for new debugging switch to
+ control which accessibility model gets employed under
+ restriction No_Dynamic_Accessibility_Checks.
+ * exp_attr.adb (Expand_N_Attribute_Reference): Disable dynamic
+ accessibility check generation when
+ No_Dynamic_Accessibility_Checks is active.
+ * exp_ch4.adb (Apply_Accessibility_Check): Skip check generation
+ when restriction No_Dynamic_Accessibility_Checks is active.
+ (Expand_N_Allocator): Disable dynamic accessibility checks when
+ No_Dynamic_Accessibility_Checks is active.
+ (Expand_N_In): Disable dynamic accessibility checks when
+ No_Dynamic_Accessibility_Checks is active.
+ (Expand_N_Type_Conversion): Disable dynamic accessibility checks
+ when No_Dynamic_Accessibility_Checks is active.
+ * exp_ch5.adb (Expand_N_Assignment_Statement): Disable
+ alternative accessibility model calculations when computing a
+ dynamic level for a SAOAAT.
+ * exp_ch6.adb (Add_Call_By_Copy_Code): Disable dynamic
+ accessibility check generation when
+ No_Dynamic_Accessibility_Checks is active.
+ (Expand_Branch): Disable alternative accessibility model
+ calculations.
+ (Expand_Call_Helper): Disable alternative accessibility model
+ calculations.
+ * restrict.adb, restrict.ads: Add new restriction
+ No_Dynamic_Accessibility_Checks.
+ (No_Dynamic_Accessibility_Checks_Enabled): Created to test when
+ experimental features (which are generally incompatible with
+ standard Ada) can be enabled.
+ * sem_attr.adb (Safe_Value_Conversions): Add handling of new
+ accessibility model under the restriction
+ No_Dynamic_Accessibility_Checks.
+ * sem_prag.adb (Process_Restrictions_Or_Restriction_Warnings):
+ Disallow new restriction No_Dynamic_Accessibility_Checks from
+ being exclusively specified within a body or subunit without
+ being present in a specification.
+ * sem_res.adb (Check_Fully_Declared_Prefix): Minor comment
+ fixup.
+ (Valid_Conversion): Omit implicit conversion checks on anonymous
+ access types and perform static checking instead when
+ No_Dynamic_Accessibility_Checks is active.
+ * sem_util.adb, sem_util.ads (Accessibility_Level): Add special
+ handling of anonymous access objects, formal parameters,
+ anonymous access components, and function return objects.
+ (Deepest_Type_Access_Level): When
+ No_Dynamic_Accessibility_Checks is active employ an alternative
+ model. Add paramter Allow_Alt_Model to override the new behavior
+ in certain cases.
+ (Type_Access_Level): When No_Dynamic_Accessibility_Checks is
+ active employ an alternative model. Add parameter
+ Allow_Alt_Model to override the new behavior in certain cases.
+ (Typ_Access_Level): Created within Accessibility_Level for
+ convenience.
+ * libgnat/s-rident.ads, snames.ads-tmpl: Add handing for
+ No_Dynamic_Accessibility_Checks.
+
+2021-07-05 Doug Rupp <rupp@adacore.com>
+
+ * adaint.h (__gnat_set_file_time_name): Use OS_Time.
+ * adaint.c (__gnat_set_file_time_name): Likewise.
+
+2021-07-05 Doug Rupp <rupp@adacore.com>
+
+ * adaint.h (OS_Time): typedef as long long.
+ * osint.adb (Underlying_OS_Time): Declare as 64-bit signed type.
+ * libgnat/s-os_lib.adb ("<"): Compare OS_Time as
+ Long_Long_Integer.
+ ("<="): Likewise.
+ (">"): Likewise.
+ (">="): Likewise.
+ * libgnat/s-os_lib.ads (OS_Time): Declare as 64-bit signed type.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_ch3.adb (Check_Abstract_Overriding): Post error message on
+ renaming node.
+
+2021-07-05 Yannick Moy <moy@adacore.com>
+
+ * libgnat/a-uncdea.ads: Add Depends/Post to
+ Ada.Unchecked_Deallocation.
+ * sem_ch4.adb (Analyze_Allocator): Remove checking of allocator
+ placement.
+ * sem_res.adb (Flag_Object): Same.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * aspects.ads: Add GNAT_Annotate aspect.
+ * gnat1drv.adb (Adjust_Global_Switches): Stop defining
+ Name_Gnat_Annotate as an alias of Name_Annotate.
+ * snames.ads-tmpl: Define Gnat_Annotate.
+ * par-prag.adb, sem_prag.ads: Add Pragma_Gnat_Annotate to list
+ of pragmas.
+ * lib-writ.adb, sem_ch13.adb, sem_prag.adb: Handle Gnat_Annotate
+ like Aspect_Annotate.
+
+2021-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * ttypes.ads (Target_Strict_Alignment): Fix comment.
+
+2021-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Has_Compatible_Alignment_Internal): Fix
+ indentation of ELSIF comments; remove explicit calls to
+ UI_To_Int; remove extra parens around the MOD operand.
+
+2021-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_aggr.adb (Resolve_Record_Aggregate, Step_5): Do not check
+ for the need to use an extension aggregate for a given component
+ when within an instance and the type of the component hss a
+ private ancestor: the instantiation is legal if the generic
+ compiles, and spurious errors may be generated otherwise.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * errout.adb (Output_JSON_Message): Recursively call
+ Output_JSON_Message for continuation messages instead of
+ appending their content to the initial message.
+
+2021-07-05 Steve Baird <baird@adacore.com>
+
+ * debug.adb: Remove comments about -gnatd_z switch.
+ * exp_ch3.adb (Make_Predefined_Primitive_Specs): A one-line fix
+ for a subtle bug that took some effort to debug. Append a new
+ Put_Image procedure for a type extension even if it seems to
+ already have one, just as is done for (for example) the
+ streaming-related Read procedure.
+ * exp_put_image.adb:
+ (Build_Record_Put_Image_Procedure.Make_Component_Attributes): Do
+ not treat _Parent component like just another component, for two
+ reasons. 1. If the _parent component's type has a
+ user-specified Put_Image procedure, then we want to generate a
+ call to that procedure and then generate extension aggregate
+ syntax. 2. Otherwise, we still don't want to see any mention of
+ "_parent" in the generated image text.
+ (Build_Record_Put_Image_Procedure.Make_Component_Name): Add
+ assertion that we are not generating a reference to an "_parent"
+ component.
+ (Build_Record_Put_Image_Procedure): Add special treatment for
+ null records. Add call to Duplicate_Subexpr for image attribute
+ prefix in order to help with expansion needed in the class-wide
+ case (where the prefix is also referenced in the call to
+ Wide_Wide_Expanded_Name) if evaluation of the prefix has side
+ effects. Add new local helper function, Put_String_Exp. Add
+ support for case where prefix type is class-wide.
+ (Enable_Put_Image, Preload_Root_Buffer_Type): Query Ada_Version
+ > Ada_2022 instead of (indirectly) querying -gnatd_z switch.
+ * freeze.adb (In_Expanded_Body): A one-line change to add
+ TSS_Put_Image to the list of subprograms that have
+ expander-created bodies.
+ * rtsfind.ads: Add support for accessing
+ Ada.Tags.Wide_Wide_Expanded_Name.
+ * sem_ch3.ads, sem_ch3.adb: Delete Is_Null_Extension function,
+ as part of moving it to Sem_Util.
+ * sem_ch13.adb
+ (Analyze_Put_Image_TSS_Definition.Has_Good_Profile): Improve
+ diagnostic messages in cases where the result is going to be
+ False and the Report parameter is True. Relax overly-restrictive
+ checks in order to implement mode conformance.
+ (Analyze_Stream_TSS_Definition.Has_Good_Profile): Add similar
+ relaxation of parameter subtype checking for the Stream
+ parameter of user-defined streaming subprograms.
+ * sem_disp.adb (Check_Dispatching_Operation): A one-line
+ change (and an accompanying comment change) to add TSS_Put_Image
+ to the list of compiler-generated dispatching primitive
+ operations.
+ * sem_util.ads, sem_util.adb: Add Ignore_Privacy Boolean
+ parameter to Is_Null_Record_Type function (typically the
+ parameter will be False when the function is being used in the
+ implementation of static semantics and True for dynamic
+ semantics; the parameter might make a difference in the case of,
+ for example, a private type that is implemented as a null record
+ type). Add related new routines Is_Null_Extension (formerly
+ declared in Sem_Ch3), Is_Null_Extension_Of, and
+ Is_Null_Record_Definition.
+
+2021-07-05 Justin Squirek <squirek@adacore.com>
+
+ * freeze.adb (Freeze_Profile): Use N's Sloc, F_type's chars.
+
+2021-07-05 Bob Duff <duff@adacore.com>
+
+ * checks.adb, exp_aggr.adb, exp_ch5.adb, freeze.adb,
+ sem_util.adb, sem_util.ads: Change L and H to be First and Last,
+ to match the attributes in the RM. Change calls from procedure
+ to function where appropriate.
+
+2021-07-05 Bob Duff <duff@adacore.com>
+
+ * sem_util.ads, sem_util.adb (Compute_Returns_By_Ref): New
+ procedure to compute Returns_By_Ref, to avoid some code
+ duplication. This will likely change soon, so it's good to have
+ the code in one place.
+ (CW_Or_Has_Controlled_Part): Move here from Exp_Ch7, because
+ it's called by Compute_Returns_By_Ref, and this is a better
+ place for it anyway.
+ (Needs_Finalization): Fix comment to be vague instead of wrong.
+ * exp_ch6.adb (Expand_N_Subprogram_Body, Freeze_Subprogram):
+ Call Compute_Returns_By_Ref.
+ * sem_ch6.adb (Check_Delayed_Subprogram): Call
+ Compute_Returns_By_Ref.
+ * exp_ch7.ads, exp_ch7.adb (CW_Or_Has_Controlled_Part): Move to
+ Sem_Util.
+ (Has_New_Controlled_Component): Remove unused function.
+
+2021-07-05 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_ch3.adb (Check_Abstract_Overriding): Check for renamings.
+
+2021-07-05 Boris Yakobowski <yakobowski@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_Rem): Remove special case for rem -1
+ in CodePeer_Mode.
+
+2021-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/101094
+ * exp_attr.adb (Get_Integer_Type): Return an integer type with the
+ same signedness as the input type.
+
2021-06-29 Richard Kenner <kenner@adacore.com>
* sem_util.adb (Visit_Node): Add handling for N_Block_Statement
diff --git a/gcc/ada/Make-generated.in b/gcc/ada/Make-generated.in
index 7d452b8..948fc50 100644
--- a/gcc/ada/Make-generated.in
+++ b/gcc/ada/Make-generated.in
@@ -83,4 +83,4 @@ ada/stamp-sdefault : $(srcdir)/ada/version.c Makefile
touch ada/stamp-sdefault
ada/%: $(srcdir)/ada/libgnat/%
- $(CP) $< $@
+ $(CP) -f $< $@
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index ff46200..fb851a6 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -275,13 +275,7 @@ GNATRTL_NONTASKING_OBJS= \
a-stboha$(objext) \
a-stfiha$(objext) \
a-stmaco$(objext) \
- a-stobbu$(objext) \
- a-stobfi$(objext) \
a-storio$(objext) \
- a-stoubu$(objext) \
- a-stoufi$(objext) \
- a-stoufo$(objext) \
- a-stouut$(objext) \
a-strbou$(objext) \
a-stream$(objext) \
a-strsto$(objext) \
@@ -295,7 +289,6 @@ GNATRTL_NONTASKING_OBJS= \
a-strsup$(objext) \
a-strunb$(objext) \
a-ststio$(objext) \
- a-stteou$(objext) \
a-sttebu$(objext) \
a-stbuun$(objext) \
a-stbubo$(objext) \
@@ -1050,7 +1043,7 @@ EXTRA_GNATRTL_NONTASKING_OBJS=
EXTRA_GNATRTL_TASKING_OBJS=
# Subsets of extra libgnat sources that always go together
-VX_SIGTRAMP_EXTRA_SRCS=sigtramp.h sigtramp-vxworks-target.inc
+VX_SIGTRAMP_EXTRA_SRCS=sigtramp.h sigtramp-vxworks-target.h
# Additional object files that should go in the same directory as libgnat,
# aside the library itself. Typically useful for crtbegin/crtend kind of files.
@@ -1095,7 +1088,7 @@ ifeq ($(strip $(filter-out powerpc% wrs vxworks vxworksspe vxworks7% vxworks7spe
s-intman.adb<libgnarl/s-intman__vxworks.adb \
s-osinte.ads<libgnarl/s-osinte__vxworks.ads \
s-osinte.adb<libgnarl/s-osinte__vxworks.adb \
- s-osprim.adb<libgnat/s-osprim__vxworks.adb \
+ s-osprim.adb<libgnat/s-osprim__posix.adb \
s-parame.ads<libgnat/s-parame__vxworks.ads \
s-parame.adb<libgnat/s-parame__vxworks.adb \
s-taprop.adb<libgnarl/s-taprop__vxworks.adb \
@@ -1346,7 +1339,7 @@ ifeq ($(strip $(filter-out %86 x86_64 wrs vxworks vxworks7%,$(target_cpu) $(targ
s-inmaop.adb<libgnarl/s-inmaop__vxworks.adb \
s-intman.ads<libgnarl/s-intman__vxworks.ads \
s-intman.adb<libgnarl/s-intman__vxworks.adb \
- s-osprim.adb<libgnat/s-osprim__vxworks.adb \
+ s-osprim.adb<libgnat/s-osprim__posix.adb \
s-parame.ads<libgnat/s-parame__vxworks.ads \
s-parame.adb<libgnat/s-parame__vxworks.adb \
s-stchop.ads<libgnat/s-stchop__limit.ads \
@@ -1493,7 +1486,7 @@ ifeq ($(strip $(filter-out aarch64 arm% coff wrs vx%,$(target_cpu) $(target_vend
s-intman.adb<libgnarl/s-intman__vxworks.adb \
s-osinte.adb<libgnarl/s-osinte__vxworks.adb \
s-osinte.ads<libgnarl/s-osinte__vxworks.ads \
- s-osprim.adb<libgnat/s-osprim__vxworks.adb \
+ s-osprim.adb<libgnat/s-osprim__posix.adb \
s-parame.ads<libgnat/s-parame__vxworks.ads \
s-parame.adb<libgnat/s-parame__vxworks.adb \
s-stchop.ads<libgnat/s-stchop__limit.ads \
@@ -2169,6 +2162,7 @@ ifeq ($(strip $(filter-out lynxos178%,$(target_os))),)
ifeq ($(strip $(filter-out lynxos178e,$(target_os))),)
LIBGNAT_TARGET_PAIRS += \
+ s-parame.ads<libgnat/s-parame__posix2008.ads \
s-osinte.ads<libgnarl/s-osinte__lynxos178e.ads \
s-osprim.adb<libgnat/s-osprim__posix2008.adb \
s-tracon.adb<hie/s-tracon__ppc-eabi.adb
@@ -2188,6 +2182,7 @@ ifeq ($(strip $(filter-out rtems%,$(target_os))),)
s-osinte.ads<libgnarl/s-osinte__rtems.ads \
s-osprim.adb<libgnat/s-osprim__rtems.adb \
s-parame.adb<libgnat/s-parame__rtems.adb \
+ s-parame.ads<libgnat/s-parame__posix2008.ads \
s-taprop.adb<libgnarl/s-taprop__posix.adb \
s-taspri.ads<libgnarl/s-taspri__posix.ads \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
@@ -2200,7 +2195,7 @@ ifeq ($(strip $(filter-out rtems%,$(target_os))),)
EH_MECHANISM=-gcc
endif
- ifeq ($(strip $(filter-out riscv%,$(target_cpu))),)
+ ifeq ($(strip $(filter-out aarch64% riscv%,$(target_cpu))),)
LIBGNAT_TARGET_PAIRS += a-nallfl.ads<libgnat/a-nallfl__wraplf.ads
endif
endif
@@ -2767,6 +2762,7 @@ ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),)
s-osinte.ads<libgnarl/s-osinte__linux.ads \
s-osinte.adb<libgnarl/s-osinte__x32.adb \
s-osprim.adb<libgnat/s-osprim__x32.adb \
+ s-parame.ads<libgnat/s-parame__posix2008.ads \
s-taprop.adb<libgnarl/s-taprop__linux.adb \
s-tasinf.ads<libgnarl/s-tasinf__linux.ads \
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index b2d4de6..26be260 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -1570,7 +1570,7 @@ extern long long __gnat_file_time(char* name)
/* Set the file time stamp. */
void
-__gnat_set_file_time_name (char *name, time_t time_stamp)
+__gnat_set_file_time_name (char *name, OS_Time time_stamp)
{
#if defined (__vxworks)
@@ -1606,7 +1606,7 @@ __gnat_set_file_time_name (char *name, time_t time_stamp)
time_t t;
/* Set modification time to requested time. */
- utimbuf.modtime = time_stamp;
+ utimbuf.modtime = (time_t) time_stamp;
/* Set access time to now in local time. */
t = time (NULL);
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index 6ef61e7..a63ceef 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -101,11 +101,7 @@ extern "C" {
#endif
/* Type corresponding to GNAT.OS_Lib.OS_Time */
-#if defined (_WIN64)
typedef long long OS_Time;
-#else
-typedef long OS_Time;
-#endif
#define __int64 long long
GNAT_STRUCT_STAT;
@@ -205,7 +201,7 @@ extern OS_Time __gnat_file_time_name (char *);
extern OS_Time __gnat_file_time_fd (int);
/* return -1 in case of error */
-extern void __gnat_set_file_time_name (char *, time_t);
+extern void __gnat_set_file_time_name (char *, OS_Time);
extern int __gnat_dup (int);
extern int __gnat_dup2 (int, int);
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index 2cbb2da..0f9ed23 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -100,6 +100,7 @@ package Aspects is
Aspect_External_Tag,
Aspect_Ghost, -- GNAT
Aspect_Global, -- GNAT
+ Aspect_GNAT_Annotate, -- GNAT
Aspect_Implicit_Dereference,
Aspect_Initial_Condition, -- GNAT
Aspect_Initializes, -- GNAT
@@ -269,6 +270,7 @@ package Aspects is
Aspect_Favor_Top_Level => True,
Aspect_Ghost => True,
Aspect_Global => True,
+ Aspect_GNAT_Annotate => True,
Aspect_Inline_Always => True,
Aspect_Invariant => True,
Aspect_Lock_Free => True,
@@ -318,9 +320,10 @@ package Aspects is
-- the same aspect attached to the same declaration are allowed.
No_Duplicates_Allowed : constant array (Aspect_Id) of Boolean :=
- (Aspect_Annotate => False,
- Aspect_Test_Case => False,
- others => True);
+ (Aspect_Annotate => False,
+ Aspect_GNAT_Annotate => False,
+ Aspect_Test_Case => False,
+ others => True);
-- The following subtype defines aspects corresponding to library unit
-- pragmas, these can only validly appear as aspects for library units,
@@ -387,6 +390,7 @@ package Aspects is
Aspect_External_Tag => Expression,
Aspect_Ghost => Optional_Expression,
Aspect_Global => Expression,
+ Aspect_GNAT_Annotate => Expression,
Aspect_Implicit_Dereference => Name,
Aspect_Initial_Condition => Expression,
Aspect_Initializes => Expression,
@@ -491,6 +495,7 @@ package Aspects is
Aspect_External_Tag => False,
Aspect_Ghost => False,
Aspect_Global => False,
+ Aspect_GNAT_Annotate => False,
Aspect_Implicit_Dereference => False,
Aspect_Initial_Condition => False,
Aspect_Initializes => False,
@@ -647,6 +652,7 @@ package Aspects is
Aspect_Full_Access_Only => Name_Full_Access_Only,
Aspect_Ghost => Name_Ghost,
Aspect_Global => Name_Global,
+ Aspect_GNAT_Annotate => Name_GNAT_Annotate,
Aspect_Implicit_Dereference => Name_Implicit_Dereference,
Aspect_Import => Name_Import,
Aspect_Independent => Name_Independent,
@@ -957,6 +963,7 @@ package Aspects is
Aspect_Extensions_Visible => Never_Delay,
Aspect_Ghost => Never_Delay,
Aspect_Global => Never_Delay,
+ Aspect_GNAT_Annotate => Never_Delay,
Aspect_Import => Never_Delay,
Aspect_Initial_Condition => Never_Delay,
Aspect_Initializes => Never_Delay,
diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
index 0995b94..42df950 100644
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -130,7 +130,7 @@ package Atree is
-- Current_Error_Node is also used for other purposes. See, for example,
-- Rtsfind.
- Current_Error_Node : Node_Id;
+ Current_Error_Node : Node_Id := Empty;
-- Node to place compiler abort messages
------------------
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 1a39a82..cebeac5 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -48,6 +48,7 @@ with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Cat; use Sem_Cat;
with Sem_Disp; use Sem_Disp;
with Sem_Eval; use Sem_Eval;
with Sem_Mech; use Sem_Mech;
@@ -84,7 +85,7 @@ package body Checks is
-- such as Apply_Scalar_Range_Check that do not insert any code can be
-- safely called even when the Expander is inactive (but Errors_Detected
-- is 0). The benefit of executing this code when expansion is off, is
- -- the ability to emit constraint error warning for static expressions
+ -- the ability to emit constraint error warnings for static expressions
-- even when we are not generating code.
-- The above is modified in gnatprove mode to ensure that proper check
@@ -379,8 +380,12 @@ package body Checks is
function Accessibility_Checks_Suppressed (E : Entity_Id) return Boolean is
begin
- if Present (E) and then Checks_May_Be_Suppressed (E) then
+ if No_Dynamic_Accessibility_Checks_Enabled (E) then
+ return True;
+
+ elsif Present (E) and then Checks_May_Be_Suppressed (E) then
return Is_Check_Suppressed (E, Accessibility_Check);
+
else
return Scope_Suppress.Suppress (Accessibility_Check);
end if;
@@ -582,6 +587,11 @@ package body Checks is
Type_Level : Node_Id;
begin
+ -- Verify we haven't tried to add a dynamic accessibility check when we
+ -- shouldn't.
+
+ pragma Assert (not No_Dynamic_Accessibility_Checks_Enabled (N));
+
if Ada_Version >= Ada_2012
and then not Present (Param_Ent)
and then Is_Entity_Name (N)
@@ -3314,13 +3324,6 @@ package body Checks is
Bad_Value (Warn => SPARK_Mode = On);
- -- In GNATprove mode, we enable the range check so that
- -- GNATprove will issue a message if it cannot be proved.
-
- if GNATprove_Mode then
- Enable_Range_Check (Expr);
- end if;
-
return;
end if;
@@ -7822,10 +7825,8 @@ package body Checks is
New_Occurrence_Of (Target_Base_Type, Loc),
Constant_Present => True,
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Target_Base_Type, Loc),
- Expression => Duplicate_Subexpr (N))),
+ Unchecked_Convert_To
+ (Target_Base_Type, Duplicate_Subexpr (N))),
Make_Raise_Constraint_Error (Loc,
Condition =>
@@ -8634,7 +8635,7 @@ package body Checks is
return;
-- Do not generate an elaboration check if the related subprogram is
- -- not subjected to accessibility checks.
+ -- not subject to elaboration checks.
elsif Elaboration_Checks_Suppressed (Subp_Id) then
return;
@@ -8644,14 +8645,20 @@ package body Checks is
elsif Restriction_Active (No_Elaboration_Code) then
return;
+ -- If pragma Pure or Preelaborate applies, then these elaboration checks
+ -- cannot fail, so do not generate them.
+
+ elsif In_Preelaborated_Unit then
+ return;
+
-- Do not generate an elaboration check if exceptions cannot be used,
-- caught, or propagated.
elsif not Exceptions_OK then
return;
- -- Do not consider subprograms which act as compilation units, because
- -- they cannot be the target of a dispatching call.
+ -- Do not consider subprograms that are compilation units, because they
+ -- cannot be the target of a dispatching call.
elsif Nkind (Context) = N_Compilation_Unit then
return;
@@ -8681,10 +8688,10 @@ package body Checks is
elsif Analyzed (Subp_Body) then
return;
- -- Do not consider primitives which occur within an instance that acts
- -- as a compilation unit. Such an instance defines its spec and body out
- -- of order (body is first) within the tree, which causes the reference
- -- to the elaboration flag to appear as an undefined symbol.
+ -- Do not consider primitives that occur within an instance that is a
+ -- compilation unit. Such an instance defines its spec and body out of
+ -- order (body is first) within the tree, which causes the reference to
+ -- the elaboration flag to appear as an undefined symbol.
elsif Within_Compilation_Unit_Instance (Subp_Id) then
return;
@@ -9757,9 +9764,6 @@ package body Checks is
when N_Attribute_Reference =>
Set_Do_Overflow_Check (N, False);
- when N_Function_Call =>
- Set_Do_Tag_Check (N, False);
-
when N_Op =>
Set_Do_Overflow_Check (N, False);
@@ -9795,7 +9799,6 @@ package body Checks is
when N_Type_Conversion =>
Set_Do_Length_Check (N, False);
- Set_Do_Tag_Check (N, False);
Set_Do_Overflow_Check (N, False);
when others =>
@@ -9931,8 +9934,7 @@ package body Checks is
declare
Indx_Type : Node_Id;
- Lo : Node_Id;
- Hi : Node_Id;
+ Bounds : Range_Nodes;
Do_Expand : Boolean := False;
begin
@@ -9942,37 +9944,38 @@ package body Checks is
Next_Index (Indx_Type);
end loop;
- Get_Index_Bounds (Indx_Type, Lo, Hi);
+ Bounds := Get_Index_Bounds (Indx_Type);
- if Nkind (Lo) = N_Identifier
- and then Ekind (Entity (Lo)) = E_In_Parameter
+ if Nkind (Bounds.First) = N_Identifier
+ and then Ekind (Entity (Bounds.First)) = E_In_Parameter
then
- Lo := Get_Discriminal (E, Lo);
+ Bounds.First := Get_Discriminal (E, Bounds.First);
Do_Expand := True;
end if;
- if Nkind (Hi) = N_Identifier
- and then Ekind (Entity (Hi)) = E_In_Parameter
+ if Nkind (Bounds.Last) = N_Identifier
+ and then Ekind (Entity (Bounds.Last)) = E_In_Parameter
then
- Hi := Get_Discriminal (E, Hi);
+ Bounds.Last := Get_Discriminal (E, Bounds.Last);
Do_Expand := True;
end if;
if Do_Expand then
- if not Is_Entity_Name (Lo) then
- Lo := Duplicate_Subexpr_No_Checks (Lo);
+ if not Is_Entity_Name (Bounds.First) then
+ Bounds.First :=
+ Duplicate_Subexpr_No_Checks (Bounds.First);
end if;
- if not Is_Entity_Name (Hi) then
- Lo := Duplicate_Subexpr_No_Checks (Hi);
+ if not Is_Entity_Name (Bounds.Last) then
+ Bounds.First := Duplicate_Subexpr_No_Checks (Bounds.Last);
end if;
N :=
Make_Op_Add (Loc,
Left_Opnd =>
Make_Op_Subtract (Loc,
- Left_Opnd => Hi,
- Right_Opnd => Lo),
+ Left_Opnd => Bounds.Last,
+ Right_Opnd => Bounds.First),
Right_Opnd => Make_Integer_Literal (Loc, 1));
return N;
@@ -10215,10 +10218,8 @@ package body Checks is
L_Index : Node_Id;
R_Index : Node_Id;
- L_Low : Node_Id;
- L_High : Node_Id;
- R_Low : Node_Id;
- R_High : Node_Id;
+ L_Bounds : Range_Nodes;
+ R_Bounds : Range_Nodes;
L_Length : Uint;
R_Length : Uint;
Ref_Node : Node_Id;
@@ -10250,29 +10251,33 @@ package body Checks is
or else
Nkind (R_Index) = N_Raise_Constraint_Error)
then
- Get_Index_Bounds (L_Index, L_Low, L_High);
- Get_Index_Bounds (R_Index, R_Low, R_High);
+ L_Bounds := Get_Index_Bounds (L_Index);
+ R_Bounds := Get_Index_Bounds (R_Index);
-- Deal with compile time length check. Note that we
-- skip this in the access case, because the access
-- value may be null, so we cannot know statically.
if not Do_Access
- and then Compile_Time_Known_Value (L_Low)
- and then Compile_Time_Known_Value (L_High)
- and then Compile_Time_Known_Value (R_Low)
- and then Compile_Time_Known_Value (R_High)
+ and then Compile_Time_Known_Value (L_Bounds.First)
+ and then Compile_Time_Known_Value (L_Bounds.Last)
+ and then Compile_Time_Known_Value (R_Bounds.First)
+ and then Compile_Time_Known_Value (R_Bounds.Last)
then
- if Expr_Value (L_High) >= Expr_Value (L_Low) then
- L_Length := Expr_Value (L_High) -
- Expr_Value (L_Low) + 1;
+ if Expr_Value (L_Bounds.Last) >=
+ Expr_Value (L_Bounds.First)
+ then
+ L_Length := Expr_Value (L_Bounds.Last) -
+ Expr_Value (L_Bounds.First) + 1;
else
L_Length := UI_From_Int (0);
end if;
- if Expr_Value (R_High) >= Expr_Value (R_Low) then
- R_Length := Expr_Value (R_High) -
- Expr_Value (R_Low) + 1;
+ if Expr_Value (R_Bounds.Last) >=
+ Expr_Value (R_Bounds.First)
+ then
+ R_Length := Expr_Value (R_Bounds.Last) -
+ Expr_Value (R_Bounds.First) + 1;
else
R_Length := UI_From_Int (0);
end if;
@@ -10304,8 +10309,9 @@ package body Checks is
(Etype (L_Index), Etype (R_Index))
and then not
- (Same_Bounds (L_Low, R_Low)
- and then Same_Bounds (L_High, R_High))
+ (Same_Bounds (L_Bounds.First, R_Bounds.First)
+ and then
+ Same_Bounds (L_Bounds.Last, R_Bounds.Last))
then
Evolve_Or_Else
(Cond, Length_E_Cond (Exptyp, T_Typ, Indx));
diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads
index 130f871..3b97bd0 100644
--- a/gcc/ada/checks.ads
+++ b/gcc/ada/checks.ads
@@ -357,7 +357,7 @@ package Checks is
-- if so inserts the appropriate run-time check.
procedure Install_Primitive_Elaboration_Check (Subp_Body : Node_Id);
- -- Insert a check which ensures that subprogram body Subp_Body has been
+ -- Insert a check to ensure that subprogram body Subp_Body has been
-- properly elaborated. The check is installed only when Subp_Body is the
-- body of a nonabstract library-level primitive of a tagged type. Further
-- restrictions may apply, see the body for details.
@@ -851,7 +851,7 @@ package Checks is
-- are not following the flow graph (more properly the flow of actual
-- processing only corresponds to the flow graph for local assignments).
-- For non-local variables, we preserve the current setting, i.e. a
- -- validity check is performed when assigning to a knonwn valid global.
+ -- validity check is performed when assigning to a known valid global.
-- Note: no validity checking is required if range checks are suppressed
-- regardless of the setting of the validity checking mode.
diff --git a/gcc/ada/comperr.adb b/gcc/ada/comperr.adb
index 1687038..064fae0 100644
--- a/gcc/ada/comperr.adb
+++ b/gcc/ada/comperr.adb
@@ -244,12 +244,17 @@ package body Comperr is
end if;
End_Line;
+
else
Write_Str ("| Error detected at ");
Write_Location (Sloc (Current_Error_Node));
End_Line;
end if;
+ Write_Str ("| Compiling ");
+ Write_Str (Get_First_Main_File_Name);
+ End_Line;
+
-- There are two cases now. If the file gnat_bug.box exists,
-- we use the contents of this file at this point.
@@ -404,6 +409,7 @@ package body Comperr is
Set_Standard_Output;
Tree_Dump;
+ Sinput.Unlock; -- so Source_Dump can modify it
Source_Dump;
raise Unrecoverable_Error;
end if;
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index 3f1fa55..5245feb3 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -140,7 +140,7 @@ package body Debug is
-- d.Z Do not enable expansion in configurable run-time mode
-- d_a Stop elaboration checks on accept or select statement
- -- d_b
+ -- d_b Use designated type model under No_Dynamic_Accessibility_Checks
-- d_c CUDA compilation : compile for the host
-- d_d
-- d_e Ignore entry calls and requeue statements for elaboration
@@ -164,7 +164,7 @@ package body Debug is
-- d_w
-- d_x Disable inline expansion of Image attribute for enumeration types
-- d_y
- -- d_z Enable Put_Image on tagged types
+ -- d_z
-- d_A Stop generation of ALI file
-- d_B Warn on build-in-place function calls
@@ -956,6 +956,10 @@ package body Debug is
-- behavior is similar to that of No_Entry_Calls_In_Elaboration_Code,
-- but does not penalize actual entry calls in elaboration code.
+ -- d_b When the restriction No_Dynamic_Accessibility_Checks is enabled,
+ -- use the simple "designated type" accessibility model, instead of
+ -- using the implicit level of the anonymous access type declaration.
+
-- d_e The compiler ignores simple entry calls, asynchronous transfer of
-- control, conditional entry calls, timed entry calls, and requeue
-- statements in both the static and dynamic elaboration models.
@@ -993,9 +997,6 @@ package body Debug is
-- d_x The compiler does not expand in line the Image attribute for user-
-- defined enumeration types and the standard boolean type.
- -- d_z Enable the default Put_Image on tagged types that are not
- -- predefined.
-
-- d_A Do not generate ALI files by setting Opt.Disable_ALI_File.
-- d_B Warn on build-in-place function calls. This allows users to
@@ -1100,7 +1101,7 @@ package body Debug is
-- issues (e.g., assuming that a low bound of an array parameter
-- of an unconstrained subtype belongs to the index subtype).
- -- d.9 Enable build-in-place for function calls returning some nonlimited
+ -- d.9 Disable build-in-place for function calls returning nonlimited
-- types.
------------------------------------------
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index 0df103b..665170c 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -1057,6 +1057,46 @@ If a component of ``T`` is itself of a record or array type, the specfied
attribute definition clause must be provided for the component type as well
if desired.
+Representation changes that explicitly or implicitly toggle the scalar storage
+order are not supported and may result in erroneous execution of the program,
+except when performed by means of an instance of ``Ada.Unchecked_Conversion``.
+
+In particular, overlays are not supported and a warning is given for them:
+
+.. code-block:: ada
+
+ type Rec_LE is record
+ I : Integer;
+ end record;
+
+ for Rec_LE use record
+ I at 0 range 0 .. 31;
+ end record;
+
+ for Rec_LE'Bit_Order use System.Low_Order_First;
+ for Rec_LE'Scalar_Storage_Order use System.Low_Order_First;
+
+ type Rec_BE is record
+ I : Integer;
+ end record;
+
+ for Rec_BE use record
+ I at 0 range 0 .. 31;
+ end record;
+
+ for Rec_BE'Bit_Order use System.High_Order_First;
+ for Rec_BE'Scalar_Storage_Order use System.High_Order_First;
+
+ R_LE : Rec_LE;
+
+ R_BE : Rec_BE;
+ for R_BE'Address use R_LE'Address;
+
+``warning: overlay changes scalar storage order [enabled by default]``
+
+In most cases, such representation changes ought to be replaced by an
+instantiation of a function or procedure provided by ``GNAT.Byte_Swapping``.
+
Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index d86a2fd..6c81ca7 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -2237,8 +2237,7 @@ of GNAT specific extensions are recognized as follows:
some restrictions (described below). Aggregate syntax is used for choices
of such a case statement; however, in cases where a "normal" aggregate would
require a discrete value, a discrete subtype may be used instead; box
- notation can also be used to match all values (but currently only
- for discrete subcomponents).
+ notation can also be used to match all values.
Consider this example:
@@ -2269,10 +2268,10 @@ of GNAT specific extensions are recognized as follows:
set shall be a proper subset of the second (and the later alternative
will not be executed if the earlier alternative "matches"). All possible
values of the composite type shall be covered. The composite type of the
- selector shall be a nonlimited untagged undiscriminated record type, all
- of whose subcomponent subtypes are either static discrete subtypes or
- record types that meet the same restrictions. Support for arrays is
- planned, but not yet implemented.
+ selector shall be a nonlimited untagged (but possibly discriminated)
+ record type, all of whose subcomponent subtypes are either static discrete
+ subtypes or record types that meet the same restrictions. Support for arrays
+ is planned, but not yet implemented.
In addition, pattern bindings are supported. This is a mechanism
for binding a name to a component of a matching value for use within
@@ -2362,6 +2361,23 @@ of GNAT specific extensions are recognized as follows:
knows the lower bound of unconstrained array formals when the formal's
subtype has index ranges with static fixed lower bounds.
+* Prefixed-view notation for calls to primitive subprograms of untagged types
+
+ Since Ada 2005, calls to primitive subprograms of a tagged type that
+ have a "prefixed view" (see RM 4.1.3(9.2)) have been allowed to be
+ written using the form of a selected_component, with the first actual
+ parameter given as the prefix and the name of the subprogram as a
+ selector. This prefixed-view notation for calls is extended so as to
+ also allow such syntax for calls to primitive subprograms of untagged
+ types. The primitives of an untagged type T that have a prefixed view
+ are those where the first formal parameter of the subprogram either
+ is of type T or is an anonymous access parameter whose designated type
+ is T. For a type that has a component that happens to have the same
+ simple name as one of the type's primitive subprograms, where the
+ component is visible at the point of a selected_component using that
+ name, preference is given to the component in a selected_component
+ (as is currently the case for tagged types with such component names).
+
.. _Pragma-Extensions_Visible:
Pragma Extensions_Visible
diff --git a/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst b/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst
index e818ab5..9f419a7 100644
--- a/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst
@@ -672,6 +672,26 @@ aliasing all views of the object (which may be manipulated by different tasks,
say) must be consistent, so it is imperative that the object, once created,
remain invariant.
+.. _Image_Values_For_Nonscalar_Types:
+
+Image Values For Nonscalar Types
+================================
+
+Ada 2022 defines the Image, Wide_Image, and Wide_Wide image attributes
+for nonscalar types; earlier Ada versions defined these attributes only
+for scalar types. Ada RM 4.10 provides some general guidance regarding
+the default implementation of these attributes and the GNAT compiler
+follows that guidance. However, beyond that the precise details of the
+image text generated in these cases are deliberately not documented and are
+subject to change. In particular, users should not rely on formatting details
+(such as spaces or line breaking), record field order, image values for access
+types, image values for types that have ancestor or subcomponent types
+declared in non-Ada2022 code, image values for predefined types, or the
+compiler's choices regarding the implementation permissions described in
+Ada RM 4.10. This list is not intended to be exhaustive. If more precise
+control of image text is required for some type T, then T'Put_Image should be
+explicitly specified.
+
.. _Strict_Conformance_to_the_Ada_Reference_Manual:
Strict Conformance to the Ada Reference Manual
diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index 6e8a772..21d7bfb 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -481,7 +481,13 @@ package body Einfo.Utils is
procedure Init_Size (Id : E; V : Int) is
begin
- pragma Assert (not Is_Object (Id));
+ pragma Assert (Is_Type (Id));
+ pragma Assert
+ (not Known_Esize (Id) or else Esize (Id) = V);
+ pragma Assert
+ (RM_Size (Id) = No_Uint
+ or else RM_Size (Id) = Uint_0
+ or else RM_Size (Id) = V);
Set_Esize (Id, UI_From_Int (V));
Set_RM_Size (Id, UI_From_Int (V));
end Init_Size;
@@ -492,7 +498,7 @@ package body Einfo.Utils is
procedure Init_Size_Align (Id : E) is
begin
- pragma Assert (not Is_Object (Id));
+ pragma Assert (Ekind (Id) in Type_Kind | E_Void);
Set_Esize (Id, Uint_0);
Set_RM_Size (Id, Uint_0);
Set_Alignment (Id, Uint_0);
@@ -591,46 +597,6 @@ package body Einfo.Utils is
and then not Is_Generic_Type (E);
end Known_Static_RM_Size;
- function Unknown_Alignment (E : Entity_Id) return B is
- begin
- return not Known_Alignment (E);
- end Unknown_Alignment;
-
- function Unknown_Component_Bit_Offset (E : Entity_Id) return B is
- begin
- return not Known_Component_Bit_Offset (E);
- end Unknown_Component_Bit_Offset;
-
- function Unknown_Component_Size (E : Entity_Id) return B is
- begin
- return not Known_Component_Size (E);
- end Unknown_Component_Size;
-
- function Unknown_Esize (E : Entity_Id) return B is
- begin
- return not Known_Esize (E);
- end Unknown_Esize;
-
- function Unknown_Normalized_First_Bit (E : Entity_Id) return B is
- begin
- return not Known_Normalized_First_Bit (E);
- end Unknown_Normalized_First_Bit;
-
- function Unknown_Normalized_Position (E : Entity_Id) return B is
- begin
- return not Known_Normalized_Position (E);
- end Unknown_Normalized_Position;
-
- function Unknown_Normalized_Position_Max (E : Entity_Id) return B is
- begin
- return not Known_Normalized_Position_Max (E);
- end Unknown_Normalized_Position_Max;
-
- function Unknown_RM_Size (E : Entity_Id) return B is
- begin
- return not Known_RM_Size (E);
- end Unknown_RM_Size;
-
--------------------
-- Address_Clause --
--------------------
@@ -2487,15 +2453,15 @@ package body Einfo.Utils is
return Direct_Primitive_Operations
(Corresponding_Record_Type (Id));
- -- If expansion is disabled the corresponding record type is absent,
- -- but if the type has ancestors it may have primitive operations.
-
- elsif Is_Tagged_Type (Id) then
- return Direct_Primitive_Operations (Id);
+ -- When expansion is disabled, the corresponding record type is
+ -- absent, but if this is a tagged type with ancestors, or if the
+ -- extension of prefixed calls for untagged types is enabled, then
+ -- it may have associated primitive operations.
else
- return No_Elist;
+ return Direct_Primitive_Operations (Id);
end if;
+
else
return Direct_Primitive_Operations (Id);
end if;
@@ -2927,8 +2893,13 @@ package body Einfo.Utils is
-----------------
function Size_Clause (Id : E) return N is
+ Result : N := Get_Attribute_Definition_Clause (Id, Attribute_Size);
begin
- return Get_Attribute_Definition_Clause (Id, Attribute_Size);
+ if No (Result) then
+ Result := Get_Attribute_Definition_Clause (Id, Attribute_Value_Size);
+ end if;
+
+ return Result;
end Size_Clause;
------------------------
diff --git a/gcc/ada/einfo-utils.ads b/gcc/ada/einfo-utils.ads
index f65dbfa..dbf3ad6 100644
--- a/gcc/ada/einfo-utils.ads
+++ b/gcc/ada/einfo-utils.ads
@@ -314,12 +314,11 @@ package Einfo.Utils is
-- Type Representation Attribute Predicates --
----------------------------------------------
- -- These predicates test the setting of the indicated attribute. If the
- -- value has been set, then Known is True, and Unknown is False. If no
- -- value is set, then Known is False and Unknown is True. The Known_Static
- -- predicate is true only if the value is set (Known) and is set to a
- -- compile time known value. Note that in the case of Alignment and
- -- Normalized_First_Bit, dynamic values are not possible, so we do not
+ -- These predicates test the setting of the indicated attribute. The
+ -- Known predicate is True if and only if the value has been set. The
+ -- Known_Static predicate is True only if the value is set (Known) and is
+ -- set to a compile time known value. Note that in the case of Alignment
+ -- and Normalized_First_Bit, dynamic values are not possible, so we do not
-- need a separate Known_Static calls in these cases. The not set (unknown)
-- values are as follows:
@@ -364,15 +363,6 @@ package Einfo.Utils is
function Known_Static_Normalized_Position_Max (E : Entity_Id) return B;
function Known_Static_RM_Size (E : Entity_Id) return B;
- function Unknown_Alignment (E : Entity_Id) return B;
- function Unknown_Component_Bit_Offset (E : Entity_Id) return B;
- function Unknown_Component_Size (E : Entity_Id) return B;
- function Unknown_Esize (E : Entity_Id) return B;
- function Unknown_Normalized_First_Bit (E : Entity_Id) return B;
- function Unknown_Normalized_Position (E : Entity_Id) return B;
- function Unknown_Normalized_Position_Max (E : Entity_Id) return B;
- function Unknown_RM_Size (E : Entity_Id) return B;
-
pragma Inline (Known_Alignment);
pragma Inline (Known_Component_Bit_Offset);
pragma Inline (Known_Component_Size);
@@ -390,15 +380,6 @@ package Einfo.Utils is
pragma Inline (Known_Static_Normalized_Position_Max);
pragma Inline (Known_Static_RM_Size);
- pragma Inline (Unknown_Alignment);
- pragma Inline (Unknown_Component_Bit_Offset);
- pragma Inline (Unknown_Component_Size);
- pragma Inline (Unknown_Esize);
- pragma Inline (Unknown_Normalized_First_Bit);
- pragma Inline (Unknown_Normalized_Position);
- pragma Inline (Unknown_Normalized_Position_Max);
- pragma Inline (Unknown_RM_Size);
-
---------------------------------------------------
-- Access to Subprograms in Subprograms_For_Type --
---------------------------------------------------
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 70b93b3..6a8d493 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -933,14 +933,15 @@ package Einfo is
-- Direct_Primitive_Operations
-- Defined in tagged types and subtypes (including synchronized types),
--- in tagged private types and in tagged incomplete types. Element list
--- of entities for primitive operations of the tagged type. Not defined
--- in untagged types. In order to follow the C++ ABI, entities of
--- primitives that come from source must be stored in this list in the
--- order of their occurrence in the sources. For incomplete types the
--- list is always empty.
--- When expansion is disabled the corresponding record type of a
--- synchronized type is not constructed. In that case, such types
+-- in tagged private types, and in tagged incomplete types. However, when
+-- Extensions_Allowed is True (-gnatX), also defined for untagged types
+-- (for support of the extension feature of prefixed calls for untagged
+-- types). This field is an element list of entities for primitive
+-- operations of the type. For incomplete types the list is always empty.
+-- In order to follow the C++ ABI, entities of primitives that come from
+-- source must be stored in this list in the order of their occurrence in
+-- the sources. When expansion is disabled, the corresponding record type
+-- of a synchronized type is not constructed. In that case, such types
-- carry this attribute directly.
-- Directly_Designated_Type
@@ -1930,8 +1931,6 @@ package Einfo is
-- that clients should generally not test this flag directly, but instead
-- use function Has_Unreferenced.
--- ??? this real description was clobbered
-
-- Has_Pragma_Unreferenced_Objects
-- Defined in all entities. Set if a valid pragma Unused applies to an
-- entity, indicating that warnings should be given if the entity is
@@ -2016,11 +2015,11 @@ package Einfo is
-- which at least one of the shift operators is defined.
-- Has_Size_Clause
--- Defined in entities for types and objects. Set if a size clause is
--- defined for the entity. Used to prevent multiple Size clauses for a
--- given entity. Note that it is always initially cleared for a derived
--- type, even though the Size for such a type is inherited from a Size
--- clause given for the parent type.
+-- Defined in entities for types and objects. Set if a size or value size
+-- clause is defined for the entity. Used to prevent multiple clauses
+-- for a given entity. Note that it is always initially cleared for a
+-- derived type, even though the Size or Value_Size clause for such a
+-- type might be inherited from an ancestor type.
-- Has_Small_Clause
-- Defined in ordinary fixed point types (but not subtypes). Indicates
@@ -4322,13 +4321,12 @@ package Einfo is
-- suppress this code if a subsequent address clause is encountered.
-- Size_Clause (synthesized)
--- Applies to all entities. If a size clause is present in the rep
--- item chain for an entity then the attribute definition clause node
--- for the size clause is returned. Otherwise Size_Clause returns Empty
--- if no item is present. Usually this is only meaningful if the flag
--- Has_Size_Clause is set. This is because when the representation item
--- chain is copied for a derived type, it can inherit a size clause that
--- is not applicable to the entity.
+-- Applies to all entities. If a size or value size clause is present in
+-- the rep item chain for an entity then that attribute definition clause
+-- is returned. Otherwise Size_Clause returns Empty. Usually this is only
+-- meaningful if the flag Has_Size_Clause is set. This is because when
+-- the representation item chain is copied for a derived type, it can
+-- inherit a size clause that is not applicable to the entity.
-- Size_Depends_On_Discriminant
-- Defined in all entities for types and subtypes. Indicates that the
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 8fd2076..0122304 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -2079,6 +2079,9 @@ package body Errout is
procedure Output_JSON_Message (Error_Id : Error_Msg_Id) is
+ function Is_Continuation (E : Error_Msg_Id) return Boolean;
+ -- Return True if E is a continuation message.
+
procedure Write_JSON_Escaped_String (Str : String_Ptr);
-- Write each character of Str, taking care of preceding each quote and
-- backslash with a backslash. Note that this escaping differs from what
@@ -2099,6 +2102,15 @@ package body Errout is
-- Span.Last are different from Span.Ptr, they will be printed as JSON
-- locations under the names "start" and "finish".
+ -----------------------
+ -- Is_Continuation --
+ -----------------------
+
+ function Is_Continuation (E : Error_Msg_Id) return Boolean is
+ begin
+ return E <= Last_Error_Msg and then Errors.Table (E).Msg_Cont;
+ end Is_Continuation;
+
-------------------------------
-- Write_JSON_Escaped_String --
-------------------------------
@@ -2155,6 +2167,10 @@ package body Errout is
E : Error_Msg_Id := Error_Id;
+ Print_Continuations : constant Boolean := not Is_Continuation (E);
+ -- Do not print continuations messages as children of the current
+ -- message if the current message is a continuation message.
+
-- Start of processing for Output_JSON_Message
begin
@@ -2186,18 +2202,27 @@ package body Errout is
Write_Str ("],""message"":""");
Write_JSON_Escaped_String (Errors.Table (E).Text);
-
- -- Print message continuations if present
+ Write_Str ("""");
E := E + 1;
- while E <= Last_Error_Msg and then Errors.Table (E).Msg_Cont loop
- Write_Str (", ");
- Write_JSON_Escaped_String (Errors.Table (E).Text);
+ if Print_Continuations and then Is_Continuation (E) then
+
+ Write_Str (",""children"": [");
+ Output_JSON_Message (E);
E := E + 1;
- end loop;
- Write_Str ("""}");
+ while Is_Continuation (E) loop
+ Write_Str (", ");
+ Output_JSON_Message (E);
+ E := E + 1;
+ end loop;
+
+ Write_Str ("]");
+
+ end if;
+
+ Write_Str ("}");
end Output_JSON_Message;
---------------------
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 56ec1be..1b08436 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -375,15 +375,6 @@ package body Exp_Aggr is
-- specifically optimized for the target.
function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean is
- Csiz : Uint := No_Uint;
- Ctyp : Entity_Id;
- Expr : Node_Id;
- High : Node_Id;
- Index : Entity_Id;
- Low : Node_Id;
- Nunits : Int;
- Remainder : Uint;
- Value : Uint;
function Is_OK_Aggregate (Aggr : Node_Id) return Boolean;
-- Return true if Aggr is suitable for back-end assignment
@@ -422,6 +413,15 @@ package body Exp_Aggr is
return Nkind (First (Assoc)) /= N_Iterated_Component_Association;
end Is_OK_Aggregate;
+ Bounds : Range_Nodes;
+ Csiz : Uint := No_Uint;
+ Ctyp : Entity_Id;
+ Expr : Node_Id;
+ Index : Entity_Id;
+ Nunits : Int;
+ Remainder : Uint;
+ Value : Uint;
+
-- Start of processing for Aggr_Assignment_OK_For_Backend
begin
@@ -444,9 +444,9 @@ package body Exp_Aggr is
Index := First_Index (Ctyp);
while Present (Index) loop
- Get_Index_Bounds (Index, Low, High);
+ Bounds := Get_Index_Bounds (Index);
- if Is_Null_Range (Low, High) then
+ if Is_Null_Range (Bounds.First, Bounds.Last) then
return False;
end if;
@@ -2282,10 +2282,12 @@ package body Exp_Aggr is
Assoc : Node_Id;
Choice : Node_Id;
Expr : Node_Id;
- High : Node_Id;
- Low : Node_Id;
Typ : Entity_Id;
+ Bounds : Range_Nodes;
+ Low : Node_Id renames Bounds.First;
+ High : Node_Id renames Bounds.Last;
+
Nb_Choices : Nat := 0;
Table : Case_Table_Type (1 .. Number_Of_Choices (N));
-- Used to sort all the different choice values
@@ -2347,7 +2349,7 @@ package body Exp_Aggr is
exit;
end if;
- Get_Index_Bounds (Choice, Low, High);
+ Bounds := Get_Index_Bounds (Choice);
if Low /= High then
Set_Loop_Actions (Assoc, New_List);
@@ -4508,11 +4510,9 @@ package body Exp_Aggr is
Is_Array : constant Boolean := Is_Array_Type (Etype (N));
Aggr_In : Node_Id;
- Aggr_Lo : Node_Id;
- Aggr_Hi : Node_Id;
+ Aggr_Bounds : Range_Nodes;
Obj_In : Node_Id;
- Obj_Lo : Node_Id;
- Obj_Hi : Node_Id;
+ Obj_Bounds : Range_Nodes;
Parent_Kind : Node_Kind;
Parent_Node : Node_Id;
@@ -4823,16 +4823,17 @@ package body Exp_Aggr is
end if;
while Present (Aggr_In) loop
- Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
- Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
+ Aggr_Bounds := Get_Index_Bounds (Aggr_In);
+ Obj_Bounds := Get_Index_Bounds (Obj_In);
-- We require static bounds for the target and a static matching
-- of low bound for the aggregate.
- if not Compile_Time_Known_Value (Obj_Lo)
- or else not Compile_Time_Known_Value (Obj_Hi)
- or else not Compile_Time_Known_Value (Aggr_Lo)
- or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
+ if not Compile_Time_Known_Value (Obj_Bounds.First)
+ or else not Compile_Time_Known_Value (Obj_Bounds.Last)
+ or else not Compile_Time_Known_Value (Aggr_Bounds.First)
+ or else Expr_Value (Aggr_Bounds.First) /=
+ Expr_Value (Obj_Bounds.First)
then
return False;
@@ -4848,8 +4849,9 @@ package body Exp_Aggr is
elsif Parent_Kind = N_Assignment_Statement
or else Is_Constrained (Etype (Parent_Node))
then
- if not Compile_Time_Known_Value (Aggr_Hi)
- or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
+ if not Compile_Time_Known_Value (Aggr_Bounds.Last)
+ or else Expr_Value (Aggr_Bounds.Last) /=
+ Expr_Value (Obj_Bounds.Last)
then
return False;
end if;
@@ -4917,13 +4919,11 @@ package body Exp_Aggr is
-- Just set the Delay flag in the cases where the transformation will be
-- done top down from above.
- if False
-
+ if
-- Internal aggregate (transformed when expanding the parent)
- or else Parent_Kind = N_Aggregate
- or else Parent_Kind = N_Extension_Aggregate
- or else Parent_Kind = N_Component_Association
+ Parent_Kind in
+ N_Aggregate | N_Extension_Aggregate | N_Component_Association
-- Allocator (see Convert_Aggr_In_Allocator)
@@ -5692,7 +5692,7 @@ package body Exp_Aggr is
-- type using the computable sizes of the aggregate and its sub-
-- aggregates.
- procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id);
+ procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id);
-- Checks that the bounds of Aggr_Bounds are within the bounds defined
-- by Index_Bounds.
@@ -5792,55 +5792,58 @@ package body Exp_Aggr is
-- Check_Bounds --
------------------
- procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id) is
- Aggr_Lo : Node_Id;
- Aggr_Hi : Node_Id;
+ procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id) is
+ Aggr_Bounds : constant Range_Nodes :=
+ Get_Index_Bounds (Aggr_Bounds_Node);
+ Ind_Bounds : constant Range_Nodes :=
+ Get_Index_Bounds (Index_Bounds_Node);
- Ind_Lo : Node_Id;
- Ind_Hi : Node_Id;
-
- Cond : Node_Id := Empty;
+ Cond : Node_Id := Empty;
begin
- Get_Index_Bounds (Aggr_Bounds, Aggr_Lo, Aggr_Hi);
- Get_Index_Bounds (Index_Bounds, Ind_Lo, Ind_Hi);
-
-- Generate the following test:
-- [constraint_error when
- -- Aggr_Lo <= Aggr_Hi and then
- -- (Aggr_Lo < Ind_Lo or else Aggr_Hi > Ind_Hi)]
+ -- Aggr_Bounds.First <= Aggr_Bounds.Last and then
+ -- (Aggr_Bounds.First < Ind_Bounds.First
+ -- or else Aggr_Bounds.Last > Ind_Bounds.Last)]
-- As an optimization try to see if some tests are trivially vacuous
-- because we are comparing an expression against itself.
- if Aggr_Lo = Ind_Lo and then Aggr_Hi = Ind_Hi then
+ if Aggr_Bounds.First = Ind_Bounds.First
+ and then Aggr_Bounds.Last = Ind_Bounds.Last
+ then
Cond := Empty;
- elsif Aggr_Hi = Ind_Hi then
+ elsif Aggr_Bounds.Last = Ind_Bounds.Last then
Cond :=
Make_Op_Lt (Loc,
- Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
- Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo));
+ Left_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
+ Right_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Ind_Bounds.First));
- elsif Aggr_Lo = Ind_Lo then
+ elsif Aggr_Bounds.First = Ind_Bounds.First then
Cond :=
Make_Op_Gt (Loc,
- Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
- Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Hi));
+ Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last),
+ Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Bounds.Last));
else
Cond :=
Make_Or_Else (Loc,
Left_Opnd =>
Make_Op_Lt (Loc,
- Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
- Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo)),
+ Left_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
+ Right_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Ind_Bounds.First)),
Right_Opnd =>
Make_Op_Gt (Loc,
- Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
- Right_Opnd => Duplicate_Subexpr (Ind_Hi)));
+ Left_Opnd => Duplicate_Subexpr (Aggr_Bounds.Last),
+ Right_Opnd => Duplicate_Subexpr (Ind_Bounds.Last)));
end if;
if Present (Cond) then
@@ -5848,8 +5851,10 @@ package body Exp_Aggr is
Make_And_Then (Loc,
Left_Opnd =>
Make_Op_Le (Loc,
- Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
- Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi)),
+ Left_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
+ Right_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last)),
Right_Opnd => Cond);
@@ -6116,8 +6121,6 @@ package body Exp_Aggr is
-- Used to sort all the different choice values
J : Pos := 1;
- Low : Node_Id;
- High : Node_Id;
begin
Assoc := First (Component_Associations (Sub_Aggr));
@@ -6128,9 +6131,13 @@ package body Exp_Aggr is
exit;
end if;
- Get_Index_Bounds (Choice, Low, High);
- Table (J).Choice_Lo := Low;
- Table (J).Choice_Hi := High;
+ declare
+ Bounds : constant Range_Nodes :=
+ Get_Index_Bounds (Choice);
+ begin
+ Table (J).Choice_Lo := Bounds.First;
+ Table (J).Choice_Hi := Bounds.Last;
+ end;
J := J + 1;
Next (Choice);
@@ -6592,8 +6599,8 @@ package body Exp_Aggr is
-- For assignments we do the assignment in place if all the component
-- associations have compile-time known values, or are default-
-- initialized limited components, e.g. tasks. For other cases we
- -- create a temporary. The analysis for safety of on-line assignment
- -- is delicate, i.e. we don't know how to do it fully yet ???
+ -- create a temporary. A full analysis for safety of in-place assignment
+ -- is delicate.
-- For allocators we assign to the designated object in place if the
-- aggregate meets the same conditions as other in-place assignments.
@@ -9144,14 +9151,6 @@ package body Exp_Aggr is
declare
Csiz : constant Nat := UI_To_Int (Component_Size (Typ));
- Lo : Node_Id;
- Hi : Node_Id;
- -- Bounds of index type
-
- Lob : Uint;
- Hib : Uint;
- -- Values of bounds if compile time known
-
function Get_Component_Val (N : Node_Id) return Uint;
-- Given a expression value N of the component type Ctyp, returns a
-- value of Csiz (component size) bits representing this value. If
@@ -9193,147 +9192,154 @@ package body Exp_Aggr is
return Val mod Uint_2 ** Csiz;
end Get_Component_Val;
+ Bounds : constant Range_Nodes := Get_Index_Bounds (First_Index (Typ));
+
-- Here we know we have a one dimensional bit packed array
begin
- Get_Index_Bounds (First_Index (Typ), Lo, Hi);
-
-- Cannot do anything if bounds are dynamic
- if not Compile_Time_Known_Value (Lo)
- or else
- not Compile_Time_Known_Value (Hi)
+ if not (Compile_Time_Known_Value (Bounds.First)
+ and then
+ Compile_Time_Known_Value (Bounds.Last))
then
return False;
end if;
- -- Or are silly out of range of int bounds
-
- Lob := Expr_Value (Lo);
- Hib := Expr_Value (Hi);
-
- if not UI_Is_In_Int_Range (Lob)
- or else
- not UI_Is_In_Int_Range (Hib)
- then
- return False;
- end if;
+ declare
+ Bounds_Vals : Range_Values;
+ -- Compile-time known values of bounds
+ begin
+ -- Or are silly out of range of int bounds
- -- At this stage we have a suitable aggregate for handling at compile
- -- time. The only remaining checks are that the values of expressions
- -- in the aggregate are compile-time known (checks are performed by
- -- Get_Component_Val), and that any subtypes or ranges are statically
- -- known.
+ Bounds_Vals.First := Expr_Value (Bounds.First);
+ Bounds_Vals.Last := Expr_Value (Bounds.Last);
- -- If the aggregate is not fully positional at this stage, then
- -- convert it to positional form. Either this will fail, in which
- -- case we can do nothing, or it will succeed, in which case we have
- -- succeeded in handling the aggregate and transforming it into a
- -- modular value, or it will stay an aggregate, in which case we
- -- have failed to create a packed value for it.
+ if not UI_Is_In_Int_Range (Bounds_Vals.First)
+ or else
+ not UI_Is_In_Int_Range (Bounds_Vals.Last)
+ then
+ return False;
+ end if;
- if Present (Component_Associations (N)) then
- Convert_To_Positional (N, Handle_Bit_Packed => True);
- return Nkind (N) /= N_Aggregate;
- end if;
+ -- At this stage we have a suitable aggregate for handling at
+ -- compile time. The only remaining checks are that the values of
+ -- expressions in the aggregate are compile-time known (checks are
+ -- performed by Get_Component_Val), and that any subtypes or
+ -- ranges are statically known.
- -- Otherwise we are all positional, so convert to proper value
+ -- If the aggregate is not fully positional at this stage, then
+ -- convert it to positional form. Either this will fail, in which
+ -- case we can do nothing, or it will succeed, in which case we
+ -- have succeeded in handling the aggregate and transforming it
+ -- into a modular value, or it will stay an aggregate, in which
+ -- case we have failed to create a packed value for it.
- declare
- Lov : constant Int := UI_To_Int (Lob);
- Hiv : constant Int := UI_To_Int (Hib);
+ if Present (Component_Associations (N)) then
+ Convert_To_Positional (N, Handle_Bit_Packed => True);
+ return Nkind (N) /= N_Aggregate;
+ end if;
- Len : constant Nat := Int'Max (0, Hiv - Lov + 1);
- -- The length of the array (number of elements)
+ -- Otherwise we are all positional, so convert to proper value
- Aggregate_Val : Uint;
- -- Value of aggregate. The value is set in the low order bits of
- -- this value. For the little-endian case, the values are stored
- -- from low-order to high-order and for the big-endian case the
- -- values are stored from high-order to low-order. Note that gigi
- -- will take care of the conversions to left justify the value in
- -- the big endian case (because of left justified modular type
- -- processing), so we do not have to worry about that here.
+ declare
+ Len : constant Nat :=
+ Int'Max (0, UI_To_Int (Bounds_Vals.Last) -
+ UI_To_Int (Bounds_Vals.First) + 1);
+ -- The length of the array (number of elements)
- Lit : Node_Id;
- -- Integer literal for resulting constructed value
+ Aggregate_Val : Uint;
+ -- Value of aggregate. The value is set in the low order bits
+ -- of this value. For the little-endian case, the values are
+ -- stored from low-order to high-order and for the big-endian
+ -- case the values are stored from high order to low order.
+ -- Note that gigi will take care of the conversions to left
+ -- justify the value in the big endian case (because of left
+ -- justified modular type processing), so we do not have to
+ -- worry about that here.
- Shift : Nat;
- -- Shift count from low order for next value
+ Lit : Node_Id;
+ -- Integer literal for resulting constructed value
- Incr : Int;
- -- Shift increment for loop
+ Shift : Nat;
+ -- Shift count from low order for next value
- Expr : Node_Id;
- -- Next expression from positional parameters of aggregate
+ Incr : Int;
+ -- Shift increment for loop
- Left_Justified : Boolean;
- -- Set True if we are filling the high order bits of the target
- -- value (i.e. the value is left justified).
+ Expr : Node_Id;
+ -- Next expression from positional parameters of aggregate
- begin
- -- For little endian, we fill up the low order bits of the target
- -- value. For big endian we fill up the high order bits of the
- -- target value (which is a left justified modular value).
+ Left_Justified : Boolean;
+ -- Set True if we are filling the high order bits of the target
+ -- value (i.e. the value is left justified).
- Left_Justified := Bytes_Big_Endian;
+ begin
+ -- For little endian, we fill up the low order bits of the
+ -- target value. For big endian we fill up the high order bits
+ -- of the target value (which is a left justified modular
+ -- value).
- -- Switch justification if using -gnatd8
+ Left_Justified := Bytes_Big_Endian;
- if Debug_Flag_8 then
- Left_Justified := not Left_Justified;
- end if;
+ -- Switch justification if using -gnatd8
- -- Switch justfification if reverse storage order
+ if Debug_Flag_8 then
+ Left_Justified := not Left_Justified;
+ end if;
- if Reverse_Storage_Order (Base_Type (Typ)) then
- Left_Justified := not Left_Justified;
- end if;
+ -- Switch justfification if reverse storage order
- if Left_Justified then
- Shift := Csiz * (Len - 1);
- Incr := -Csiz;
- else
- Shift := 0;
- Incr := +Csiz;
- end if;
+ if Reverse_Storage_Order (Base_Type (Typ)) then
+ Left_Justified := not Left_Justified;
+ end if;
- -- Loop to set the values
+ if Left_Justified then
+ Shift := Csiz * (Len - 1);
+ Incr := -Csiz;
+ else
+ Shift := 0;
+ Incr := +Csiz;
+ end if;
- if Len = 0 then
- Aggregate_Val := Uint_0;
- else
- Expr := First (Expressions (N));
- Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
+ -- Loop to set the values
- for J in 2 .. Len loop
- Shift := Shift + Incr;
- Next (Expr);
- Aggregate_Val :=
- Aggregate_Val + Get_Component_Val (Expr) * Uint_2 ** Shift;
- end loop;
- end if;
+ if Len = 0 then
+ Aggregate_Val := Uint_0;
+ else
+ Expr := First (Expressions (N));
+ Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
+
+ for J in 2 .. Len loop
+ Shift := Shift + Incr;
+ Next (Expr);
+ Aggregate_Val :=
+ Aggregate_Val +
+ Get_Component_Val (Expr) * Uint_2 ** Shift;
+ end loop;
+ end if;
- -- Now we can rewrite with the proper value
+ -- Now we can rewrite with the proper value
- Lit := Make_Integer_Literal (Loc, Intval => Aggregate_Val);
- Set_Print_In_Hex (Lit);
+ Lit := Make_Integer_Literal (Loc, Intval => Aggregate_Val);
+ Set_Print_In_Hex (Lit);
- -- Construct the expression using this literal. Note that it is
- -- important to qualify the literal with its proper modular type
- -- since universal integer does not have the required range and
- -- also this is a left justified modular type, which is important
- -- in the big-endian case.
+ -- Construct the expression using this literal. Note that it
+ -- is important to qualify the literal with its proper modular
+ -- type since universal integer does not have the required
+ -- range and also this is a left justified modular type,
+ -- which is important in the big-endian case.
- Rewrite (N,
- Unchecked_Convert_To (Typ,
- Make_Qualified_Expression (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Packed_Array_Impl_Type (Typ), Loc),
- Expression => Lit)));
+ Rewrite (N,
+ Unchecked_Convert_To (Typ,
+ Make_Qualified_Expression (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Packed_Array_Impl_Type (Typ), Loc),
+ Expression => Lit)));
- Analyze_And_Resolve (N, Typ);
- return True;
+ Analyze_And_Resolve (N, Typ);
+ return True;
+ end;
end;
end;
@@ -9408,8 +9414,6 @@ package body Exp_Aggr is
(Obj_Type : Entity_Id;
Typ : Entity_Id) return Boolean
is
- L1, L2, H1, H2 : Node_Id;
-
begin
-- No sliding if the type of the object is not established yet, if it is
-- an unconstrained type whose actual subtype comes from the aggregate,
@@ -9427,20 +9431,25 @@ package body Exp_Aggr is
else
-- Sliding can only occur along the first dimension
- Get_Index_Bounds (First_Index (Typ), L1, H1);
- Get_Index_Bounds (First_Index (Obj_Type), L2, H2);
+ declare
+ Bounds1 : constant Range_Nodes :=
+ Get_Index_Bounds (First_Index (Typ));
+ Bounds2 : constant Range_Nodes :=
+ Get_Index_Bounds (First_Index (Obj_Type));
- if not Is_OK_Static_Expression (L1) or else
- not Is_OK_Static_Expression (L2) or else
- not Is_OK_Static_Expression (H1) or else
- not Is_OK_Static_Expression (H2)
- then
- return False;
- else
- return Expr_Value (L1) /= Expr_Value (L2)
- or else
- Expr_Value (H1) /= Expr_Value (H2);
- end if;
+ begin
+ if not Is_OK_Static_Expression (Bounds1.First) or else
+ not Is_OK_Static_Expression (Bounds2.First) or else
+ not Is_OK_Static_Expression (Bounds1.Last) or else
+ not Is_OK_Static_Expression (Bounds2.Last)
+ then
+ return False;
+ else
+ return Expr_Value (Bounds1.First) /= Expr_Value (Bounds2.First)
+ or else
+ Expr_Value (Bounds1.Last) /= Expr_Value (Bounds2.Last);
+ end if;
+ end;
end if;
end Must_Slide;
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 2e1cb85..f074521 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -117,8 +117,7 @@ package body Exp_Attr is
procedure Compile_Stream_Body_In_Scope
(N : Node_Id;
Decl : Node_Id;
- Arr : Entity_Id;
- Check : Boolean);
+ Arr : Entity_Id);
-- The body for a stream subprogram may be generated outside of the scope
-- of the type. If the type is fully private, it may depend on the full
-- view of other types (e.g. indexes) that are currently private as well.
@@ -867,8 +866,7 @@ package body Exp_Attr is
procedure Compile_Stream_Body_In_Scope
(N : Node_Id;
Decl : Node_Id;
- Arr : Entity_Id;
- Check : Boolean)
+ Arr : Entity_Id)
is
C_Type : constant Entity_Id := Base_Type (Component_Type (Arr));
Curr : constant Entity_Id := Current_Scope;
@@ -922,11 +920,7 @@ package body Exp_Attr is
Install := False;
end if;
- if Check then
- Insert_Action (N, Decl);
- else
- Insert_Action (N, Decl, Suppress => All_Checks);
- end if;
+ Insert_Action (N, Decl);
if Install then
@@ -1851,14 +1845,13 @@ package body Exp_Attr is
----------------------
function Get_Integer_Type (Typ : Entity_Id) return Entity_Id is
- Siz : constant Uint := Esize (Base_Type (Typ));
+ Siz : constant Uint := Esize (Base_Type (Typ));
begin
-- We need to accommodate invalid values of the base type since we
- -- accept them for Enum_Rep and Pos, so we reason on the Esize. And
- -- we use an unsigned type since the enumeration type is unsigned.
+ -- accept them for Enum_Rep and Pos, so we reason on the Esize.
- return Small_Integer_Type_For (Siz, Uns => True);
+ return Small_Integer_Type_For (Siz, Uns => Is_Unsigned_Type (Typ));
end Get_Integer_Type;
---------------------------------
@@ -2367,6 +2360,7 @@ package body Exp_Attr is
= E_Anonymous_Access_Type
and then Present (Extra_Accessibility
(Entity (Prefix (Enc_Object))))
+ and then not No_Dynamic_Accessibility_Checks_Enabled (Enc_Object)
then
Apply_Accessibility_Check (Prefix (Enc_Object), Typ, N);
@@ -2805,10 +2799,9 @@ package body Exp_Attr is
Name =>
New_Occurrence_Of (RTE (RE_Callable), Loc),
Parameter_Associations => New_List (
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RO_ST_Task_Id), Loc),
- Expression => Build_Disp_Get_Task_Id_Call (Pref)))));
+ Unchecked_Convert_To
+ (RTE (RO_ST_Task_Id),
+ Build_Disp_Get_Task_Id_Call (Pref)))));
else
Rewrite (N, Build_Call_With_Task (Pref, RTE (RE_Callable)));
@@ -4128,7 +4121,7 @@ package body Exp_Attr is
elsif Is_Array_Type (U_Type) then
Build_Array_Input_Function (Loc, U_Type, Decl, Fname);
- Compile_Stream_Body_In_Scope (N, Decl, U_Type, Check => False);
+ Compile_Stream_Body_In_Scope (N, Decl, U_Type);
-- Dispatching case with class-wide type
@@ -5238,7 +5231,7 @@ package body Exp_Attr is
elsif Is_Array_Type (U_Type) then
Build_Array_Output_Procedure (Loc, U_Type, Decl, Pname);
- Compile_Stream_Body_In_Scope (N, Decl, U_Type, Check => False);
+ Compile_Stream_Body_In_Scope (N, Decl, U_Type);
-- Class-wide case, first output external tag, then dispatch
-- to the appropriate primitive Output function (RM 13.13.2(31)).
@@ -6090,7 +6083,7 @@ package body Exp_Attr is
elsif Is_Array_Type (U_Type) then
Build_Array_Read_Procedure (N, U_Type, Decl, Pname);
- Compile_Stream_Body_In_Scope (N, Decl, U_Type, Check => False);
+ Compile_Stream_Body_In_Scope (N, Decl, U_Type);
-- Tagged type case, use the primitive Read function. Note that
-- this will dispatch in the class-wide case which is what we want
@@ -6129,11 +6122,7 @@ package body Exp_Attr is
(Loc, Full_Base (U_Type), Decl, Pname);
end if;
- -- Suppress checks, uninitialized or otherwise invalid
- -- data does not cause constraint errors to be raised for
- -- a complete record read.
-
- Insert_Action (N, Decl, All_Checks);
+ Insert_Action (N, Decl);
end if;
end if;
@@ -6756,10 +6745,9 @@ package body Exp_Attr is
Name =>
New_Occurrence_Of (RTE (RE_Terminated), Loc),
Parameter_Associations => New_List (
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RO_ST_Task_Id), Loc),
- Expression => Build_Disp_Get_Task_Id_Call (Pref)))));
+ Unchecked_Convert_To
+ (RTE (RO_ST_Task_Id),
+ Build_Disp_Get_Task_Id_Call (Pref)))));
elsif Restricted_Profile then
Rewrite (N,
@@ -7718,7 +7706,7 @@ package body Exp_Attr is
elsif Is_Array_Type (U_Type) then
Build_Array_Write_Procedure (N, U_Type, Decl, Pname);
- Compile_Stream_Body_In_Scope (N, Decl, U_Type, Check => False);
+ Compile_Stream_Body_In_Scope (N, Decl, U_Type);
-- Tagged type case, use the primitive Write function. Note that
-- this will dispatch in the class-wide case which is what we want
diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb
index 6058826..40288e4 100644
--- a/gcc/ada/exp_ch11.adb
+++ b/gcc/ada/exp_ch11.adb
@@ -1088,10 +1088,19 @@ package body Exp_Ch11 is
-- (protecting test only needed if not at library level)
- -- exceptF : Boolean := True -- static data
+ -- exceptF : aliased System.Atomic_Operations.Test_And_Set.
+ -- .Test_And_Set_Flag := 0; -- static data
+ -- if not Atomic_Test_And_Set (exceptF) then
+ -- Register_Exception (except'Unrestricted_Access);
+ -- end if;
+
+ -- If a No_Tasking restriction is in effect, or if Test_And_Set_Flag
+ -- is unavailable, then use Boolean instead. In that case, we generate:
+ --
+ -- exceptF : Boolean := True; -- static data
-- if exceptF then
- -- exceptF := False;
- -- Register_Exception (except'Unchecked_Access);
+ -- ExceptF := False;
+ -- Register_Exception (except'Unrestricted_Access);
-- end if;
procedure Expand_N_Exception_Declaration (N : Node_Id) is
@@ -1275,7 +1284,7 @@ package body Exp_Ch11 is
Force_Static_Allocation_Of_Referenced_Objects (Expression (N));
- -- Register_Exception (except'Unchecked_Access);
+ -- Register_Exception (except'Unrestricted_Access);
if not No_Exception_Handlers_Set
and then not Restriction_Active (No_Exception_Registration)
@@ -1296,27 +1305,59 @@ package body Exp_Ch11 is
Flag_Id :=
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Id), 'F'));
-
- Insert_Action (N,
- Make_Object_Declaration (Loc,
- Defining_Identifier => Flag_Id,
- Object_Definition =>
- New_Occurrence_Of (Standard_Boolean, Loc),
- Expression =>
- New_Occurrence_Of (Standard_True, Loc)));
-
Set_Is_Statically_Allocated (Flag_Id);
- Append_To (L,
- Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Flag_Id, Loc),
- Expression => New_Occurrence_Of (Standard_False, Loc)));
+ declare
+ Use_Test_And_Set_Flag : constant Boolean :=
+ (not Global_No_Tasking)
+ and then RTE_Available (RE_Test_And_Set_Flag);
+
+ Flag_Decl : Node_Id;
+ Condition : Node_Id;
+ begin
+ if Use_Test_And_Set_Flag then
+ Flag_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Flag_Id,
+ Aliased_Present => True,
+ Object_Definition =>
+ New_Occurrence_Of (RTE (RE_Test_And_Set_Flag), Loc),
+ Expression =>
+ Make_Integer_Literal (Loc, 0));
+ else
+ Flag_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Flag_Id,
+ Object_Definition =>
+ New_Occurrence_Of (Standard_Boolean, Loc),
+ Expression =>
+ New_Occurrence_Of (Standard_True, Loc));
+ end if;
- Insert_After_And_Analyze (N,
- Make_Implicit_If_Statement (N,
- Condition => New_Occurrence_Of (Flag_Id, Loc),
- Then_Statements => L));
+ Insert_Action (N, Flag_Decl);
+
+ if Use_Test_And_Set_Flag then
+ Condition :=
+ Make_Op_Not (Loc,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of
+ (RTE (RE_Atomic_Test_And_Set), Loc),
+ Parameter_Associations =>
+ New_List (New_Occurrence_Of (Flag_Id, Loc))));
+ else
+ Condition := New_Occurrence_Of (Flag_Id, Loc);
+
+ Append_To (L,
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Flag_Id, Loc),
+ Expression => New_Occurrence_Of (Standard_False, Loc)));
+ end if;
+ Insert_After_And_Analyze (N,
+ Make_Implicit_If_Statement (N,
+ Condition => Condition,
+ Then_Statements => L));
+ end;
else
Insert_List_After_And_Analyze (N, L);
end if;
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 4dbaadd..ad82e56 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -1926,6 +1926,7 @@ package body Exp_Ch3 is
Proc_Id : Entity_Id;
Rec_Type : Entity_Id;
Set_Tag : Entity_Id := Empty;
+ Has_Late_Init_Comp : Boolean := False; -- set in Build_Init_Statements
function Build_Assignment
(Id : Entity_Id;
@@ -2021,35 +2022,27 @@ package body Exp_Ch3 is
Selector_Name => New_Occurrence_Of (Id, Default_Loc));
Set_Assignment_OK (Lhs);
- -- 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
- -- the expression being given by such an attribute, but does not
- -- cover uses nested within an initial value expression. Nested
- -- uses are unlikely to occur in practice, but are theoretically
- -- possible.) It is not clear how to handle them without fully
- -- traversing the expression. ???
-
- if Kind = N_Attribute_Reference
- and then Attribute_Name (Default) in Name_Unchecked_Access
- | Name_Unrestricted_Access
- and then Is_Entity_Name (Prefix (Default))
- and then Is_Type (Entity (Prefix (Default)))
- and then Entity (Prefix (Default)) = Rec_Type
- then
- Exp :=
- Make_Attribute_Reference (Default_Loc,
- Prefix =>
- Make_Identifier (Default_Loc, Name_uInit),
- Attribute_Name => Name_Unrestricted_Access);
- end if;
-
-- Take a copy of Exp to ensure that later copies of this component
-- declaration in derived types see the original tree, not a node
-- rewritten during expansion of the init_proc. If the copy contains
-- itypes, the scope of the new itypes is the init_proc being built.
- Exp := New_Copy_Tree (Exp, New_Scope => Proc_Id);
+ declare
+ Map : Elist_Id := No_Elist;
+ begin
+ if Has_Late_Init_Comp then
+ -- Map the type to the _Init parameter in order to
+ -- handle "current instance" references.
+
+ Map := New_Elmt_List
+ (Elmt1 => Rec_Type,
+ Elmt2 => Defining_Identifier (First
+ (Parameter_Specifications
+ (Parent (Proc_Id)))));
+ end if;
+
+ Exp := New_Copy_Tree (Exp, New_Scope => Proc_Id, Map => Map);
+ end;
Res := New_List (
Make_Assignment_Statement (Loc,
@@ -2981,7 +2974,6 @@ package body Exp_Ch3 is
Counter_Id : Entity_Id := Empty;
Comp_Loc : Source_Ptr;
Decl : Node_Id;
- Has_Late_Init_Comp : Boolean;
Id : Entity_Id;
Parent_Stmts : List_Id;
Stmts : List_Id;
@@ -3097,10 +3089,9 @@ package body Exp_Ch3 is
function Find_Current_Instance
(N : Node_Id) return Traverse_Result is
begin
- if Nkind (N) = N_Attribute_Reference
- and then Is_Access_Type (Etype (N))
- and then Is_Entity_Name (Prefix (N))
- and then Is_Type (Entity (Prefix (N)))
+ if Is_Entity_Name (N)
+ and then Present (Entity (N))
+ and then Is_Current_Instance (N)
then
References_Current_Instance := True;
return Abandon;
@@ -3255,8 +3246,6 @@ package body Exp_Ch3 is
-- step deals with regular components. The second step deals with
-- components that require late initialization.
- Has_Late_Init_Comp := False;
-
-- First pass : regular components
Decl := First_Non_Pragma (Component_Items (Comp_List));
@@ -6011,7 +6000,7 @@ package body Exp_Ch3 is
-- The parent type is private then we need to inherit any TSS operations
-- from the full view.
- if Ekind (Par_Id) in Private_Kind
+ if Is_Private_Type (Par_Id)
and then Present (Full_View (Par_Id))
then
Par_Id := Base_Type (Full_View (Par_Id));
@@ -6047,7 +6036,7 @@ package body Exp_Ch3 is
-- If the derived type itself is private with a full view, then
-- associate the full view with the inherited TSS_Elist as well.
- if Ekind (B_Id) in Private_Kind
+ if Is_Private_Type (B_Id)
and then Present (Full_View (B_Id))
then
Ensure_Freeze_Node (Base_Type (Full_View (B_Id)));
@@ -10345,9 +10334,14 @@ package body Exp_Ch3 is
-- Spec of Put_Image
- if Enable_Put_Image (Tag_Typ)
- and then No (TSS (Tag_Typ, TSS_Put_Image))
+ if (not No_Run_Time_Mode)
+ and then RTE_Available (RE_Root_Buffer_Type)
then
+ -- No_Run_Time_Mode implies that the declaration of Tag_Typ
+ -- (like any tagged type) will be rejected. Given this, avoid
+ -- cascading errors associated with the Tag_Typ's TSS_Put_Image
+ -- procedure.
+
Append_To (Res, Predef_Spec_Or_Body (Loc,
Tag_Typ => Tag_Typ,
Name => Make_TSS_Name (Tag_Typ, TSS_Put_Image),
@@ -10949,8 +10943,9 @@ package body Exp_Ch3 is
-- Body of Put_Image
- if Enable_Put_Image (Tag_Typ)
- and then No (TSS (Tag_Typ, TSS_Put_Image))
+ if No (TSS (Tag_Typ, TSS_Put_Image))
+ and then (not No_Run_Time_Mode)
+ and then RTE_Available (RE_Root_Buffer_Type)
then
Build_Record_Put_Image_Procedure (Loc, Tag_Typ, Decl, Ent);
Append_To (Res, Decl);
@@ -11253,12 +11248,7 @@ package body Exp_Ch3 is
or else not Is_Abstract_Type (Typ)
or else not Is_Derived_Type (Typ))
and then not Has_Unknown_Discriminants (Typ)
- and then not
- (Is_Interface (Typ)
- and then
- (Is_Task_Interface (Typ)
- or else Is_Protected_Interface (Typ)
- or else Is_Synchronized_Interface (Typ)))
+ and then not Is_Concurrent_Interface (Typ)
and then not Restriction_Active (No_Streams)
and then not Restriction_Active (No_Dispatch)
and then No (No_Tagged_Streams_Pragma (Typ))
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index a9fc2705..16f513e 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -615,6 +615,7 @@ package body Exp_Ch4 is
and then Is_Class_Wide_Type (DesigT)
and then Tagged_Type_Expansion
and then not Scope_Suppress.Suppress (Accessibility_Check)
+ and then not No_Dynamic_Accessibility_Checks_Enabled (Ref)
and then
(Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
or else
@@ -1165,6 +1166,9 @@ package body Exp_Ch4 is
-- secondary stack). In that case, the object will be moved, so we do
-- want to Adjust. However, if it's a nonlimited build-in-place
-- function call, Adjust is not wanted.
+ --
+ -- Needs_Finalization (DesigT) can differ from Needs_Finalization (T)
+ -- if one of the two types is class-wide, and the other is not.
if Needs_Finalization (DesigT)
and then Needs_Finalization (T)
@@ -5277,6 +5281,8 @@ package body Exp_Ch4 is
if Ada_Version >= Ada_2005
and then
Ekind (Etype (Nod)) = E_Anonymous_Access_Type
+ and then not
+ No_Dynamic_Accessibility_Checks_Enabled (Nod)
then
Apply_Accessibility_Check
(Nod, Typ, Insert_Node => Nod);
@@ -6865,6 +6871,7 @@ package body Exp_Ch4 is
if Ada_Version >= Ada_2012
and then Is_Acc
and then Ekind (Ltyp) = E_Anonymous_Access_Type
+ and then not No_Dynamic_Accessibility_Checks_Enabled (Lop)
then
declare
Expr_Entity : Entity_Id := Empty;
@@ -10393,7 +10400,9 @@ package body Exp_Ch4 is
-- types and this is really marginal). We will just assume that we need
-- the test if the left operand can be negative at all.
- if Lneg and Rneg then
+ if (Lneg and Rneg)
+ and then not CodePeer_Mode
+ then
Rewrite (N,
Make_If_Expression (Loc,
Expressions => New_List (
@@ -11986,9 +11995,8 @@ package body Exp_Ch4 is
-- unchecked conversion to the target fixed-point type.
Conv :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
- Expression => New_Occurrence_Of (Expr_Id, Loc));
+ Unchecked_Convert_To
+ (Target_Type, New_Occurrence_Of (Expr_Id, Loc));
end;
-- All other conversions
@@ -12331,6 +12339,7 @@ package body Exp_Ch4 is
and then Ekind (Etype (Operand_Acc)) = E_Anonymous_Access_Type
and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
or else Attribute_Name (Original_Node (N)) = Name_Access)
+ and then not No_Dynamic_Accessibility_Checks_Enabled (N)
then
if not Comes_From_Source (N)
and then Nkind (Parent (N)) in N_Function_Call
@@ -12508,10 +12517,7 @@ package body Exp_Ch4 is
Conv : Node_Id;
begin
Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
- Conv :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
- Expression => Relocate_Node (Expression (N)));
+ Conv := Unchecked_Convert_To (Target_Type, Expression (N));
Rewrite (N, Conv);
Analyze_And_Resolve (N, Target_Type);
end;
@@ -12741,7 +12747,16 @@ package body Exp_Ch4 is
-- guard is necessary to prevent infinite recursions when we generate
-- internal conversions for the purpose of checking predicates.
- if Predicate_Enabled (Target_Type)
+ -- A view conversion of a tagged object is an object and can appear
+ -- in an assignment context, in which case no predicate check applies
+ -- to the now-dead value.
+
+ if Nkind (Parent (N)) = N_Assignment_Statement
+ and then N = Name (Parent (N))
+ then
+ null;
+
+ elsif Predicate_Enabled (Target_Type)
and then Target_Type /= Operand_Type
and then Comes_From_Source (N)
then
@@ -14936,7 +14951,17 @@ package body Exp_Ch4 is
-- Hook := null;
-- end if;
+ -- Note that the value returned by Find_Hook_Context may be an operator
+ -- node, which is not a list member. We must locate the proper node in
+ -- in the tree after which to insert the finalization code.
+
else
+ while not Is_List_Member (Fin_Context) loop
+ Fin_Context := Parent (Fin_Context);
+ end loop;
+
+ pragma Assert (Present (Fin_Context));
+
Insert_Action_After (Fin_Context,
Make_Implicit_If_Statement (Obj_Decl,
Condition =>
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 0070706..8ac9662 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -1500,12 +1500,13 @@ package body Exp_Ch5 is
(if Nkind (Name (N)) = N_Slice
then Get_Index_Bounds (Discrete_Range (Name (N)))
else Larray_Bounds);
- -- If the left-hand side is A (L..H), Larray_Bounds is A'Range, and
- -- L_Bounds is L..H. If it's not a slice, we treat it like a slice
- -- starting at A'First.
+ -- If the left-hand side is A (First..Last), Larray_Bounds is A'Range,
+ -- and L_Bounds is First..Last. If it's not a slice, we treat it like
+ -- a slice starting at A'First.
L_Bit : constant Node_Id :=
- Make_Integer_Literal (Loc, (L_Bounds.L - Larray_Bounds.L) * C_Size);
+ Make_Integer_Literal
+ (Loc, (L_Bounds.First - Larray_Bounds.First) * C_Size);
Rarray_Bounds : constant Range_Values :=
Get_Index_Bounds (First_Index (R_Typ));
@@ -1515,7 +1516,8 @@ package body Exp_Ch5 is
else Rarray_Bounds);
R_Bit : constant Node_Id :=
- Make_Integer_Literal (Loc, (R_Bounds.L - Rarray_Bounds.L) * C_Size);
+ Make_Integer_Literal
+ (Loc, (R_Bounds.First - Rarray_Bounds.First) * C_Size);
Size : constant Node_Id :=
Make_Op_Multiply (Loc,
@@ -1594,17 +1596,21 @@ package body Exp_Ch5 is
Rev : Boolean) return Node_Id
is
+ L : constant Node_Id := Name (N);
+ R : constant Node_Id := Expression (N);
+ -- Left- and right-hand sides of the assignment statement
+
Slices : constant Boolean :=
- Nkind (Name (N)) = N_Slice or else Nkind (Expression (N)) = N_Slice;
+ Nkind (L) = N_Slice or else Nkind (R) = N_Slice;
L_Prefix_Comp : constant Boolean :=
-- True if the left-hand side is a slice of a component or slice
- Nkind (Name (N)) = N_Slice
- and then Nkind (Prefix (Name (N))) in
+ Nkind (L) = N_Slice
+ and then Nkind (Prefix (L)) in
N_Selected_Component | N_Indexed_Component | N_Slice;
R_Prefix_Comp : constant Boolean :=
-- Likewise for the right-hand side
- Nkind (Expression (N)) = N_Slice
- and then Nkind (Prefix (Expression (N))) in
+ Nkind (R) = N_Slice
+ and then Nkind (Prefix (R)) in
N_Selected_Component | N_Indexed_Component | N_Slice;
begin
@@ -1664,27 +1670,28 @@ package body Exp_Ch5 is
Get_Index_Bounds (Right_Base_Index);
Known_Left_Slice_Low : constant Boolean :=
- (if Nkind (Name (N)) = N_Slice
+ (if Nkind (L) = N_Slice
then Compile_Time_Known_Value
- (Get_Index_Bounds (Discrete_Range (Name (N))).L));
+ (Get_Index_Bounds (Discrete_Range (L)).First));
Known_Right_Slice_Low : constant Boolean :=
- (if Nkind (Expression (N)) = N_Slice
+ (if Nkind (R) = N_Slice
then Compile_Time_Known_Value
- (Get_Index_Bounds (Discrete_Range (Expression (N))).H));
+ (Get_Index_Bounds (Discrete_Range (R)).Last));
Val_Bits : constant Pos := Standard_Long_Long_Integer_Size / 2;
begin
- if Left_Base_Range.H - Left_Base_Range.L < Val_Bits
- and then Right_Base_Range.H - Right_Base_Range.L < Val_Bits
+ if Left_Base_Range.Last - Left_Base_Range.First < Val_Bits
+ and then Right_Base_Range.Last - Right_Base_Range.First <
+ Val_Bits
and then Known_Esize (L_Type)
and then Known_Esize (R_Type)
and then Known_Left_Slice_Low
and then Known_Right_Slice_Low
and then Compile_Time_Known_Value
- (Get_Index_Bounds (First_Index (Etype (Larray))).L)
+ (Get_Index_Bounds (First_Index (Etype (Larray))).First)
and then Compile_Time_Known_Value
- (Get_Index_Bounds (First_Index (Etype (Rarray))).L)
+ (Get_Index_Bounds (First_Index (Etype (Rarray))).First)
and then
not (Is_Enumeration_Type (Etype (Left_Base_Index))
and then Has_Enumeration_Rep_Clause
@@ -2764,7 +2771,9 @@ package body Exp_Ch5 is
(Entity (Lhs)), Loc),
Expression =>
Accessibility_Level
- (Rhs, Dynamic_Level));
+ (Expr => Rhs,
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False));
begin
if not Accessibility_Checks_Suppressed (Entity (Lhs)) then
@@ -3375,9 +3384,17 @@ package body Exp_Ch5 is
and then Is_Discrete_Type (Etype (Pattern))
and then Compile_Time_Known_Value (Pattern)
then
- return Make_Op_Eq (Loc,
- Object,
- Make_Integer_Literal (Loc, Expr_Value (Pattern)));
+ declare
+ Val : Node_Id;
+ begin
+ if Is_Enumeration_Type (Etype (Pattern)) then
+ Val := Get_Enum_Lit_From_Pos
+ (Etype (Pattern), Expr_Value (Pattern), Loc);
+ else
+ Val := Make_Integer_Literal (Loc, Expr_Value (Pattern));
+ end if;
+ return Make_Op_Eq (Loc, Object, Val);
+ end;
end if;
case Nkind (Pattern) is
@@ -3624,16 +3641,37 @@ package body Exp_Ch5 is
return Result;
end Elsif_Parts;
+ function Else_Statements return List_Id;
+ -- Returns a "raise Constraint_Error" statement if
+ -- exception propagate is permitted and No_List otherwise.
+
+ ---------------------
+ -- Else_Statements --
+ ---------------------
+
+ function Else_Statements return List_Id is
+ begin
+ if Restriction_Active (No_Exception_Propagation) then
+ return No_List;
+ else
+ return New_List (Make_Raise_Constraint_Error (Loc,
+ Reason => CE_Invalid_Data));
+ end if;
+ end Else_Statements;
+
+ -- Local constants
+
If_Stmt : constant Node_Id :=
Make_If_Statement (Loc,
Condition => Top_Level_Pattern_Match_Condition (First_Alt),
Then_Statements => Statements (First_Alt),
- Elsif_Parts => Elsif_Parts);
- -- Do we want an implicit "else raise Program_Error" here???
- -- Perhaps only if Exception-related restrictions are not in effect.
+ Elsif_Parts => Elsif_Parts,
+ Else_Statements => Else_Statements);
Declarations : constant List_Id := New_List (Selector_Decl);
+ -- Start of processing for Expand_General_Case_Statment
+
begin
if Present (Choice_Index_Decl) then
Append_To (Declarations, Choice_Index_Decl);
@@ -4068,7 +4106,6 @@ package body Exp_Ch5 is
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Element), 'C'));
Elmt_Decl : Node_Id;
- Elmt_Ref : Node_Id;
Element_Op : constant Entity_Id :=
Get_Iterable_Type_Primitive (Container_Typ, Name_Element);
@@ -4079,19 +4116,10 @@ package body Exp_Ch5 is
begin
-- For an element iterator, the Element aspect must be present,
- -- (this is checked during analysis) and the expansion takes the form:
+ -- (this is checked during analysis).
- -- Cursor : Cursor_Type := First (Container);
- -- Elmt : Element_Type;
- -- while Has_Element (Cursor, Container) loop
- -- Elmt := Element (Container, Cursor);
- -- <original loop statements>
- -- Cursor := Next (Container, Cursor);
- -- end loop;
-
- -- However this expansion is not legal if the element is indefinite.
- -- In that case we create a block to hold a variable declaration
- -- initialized with a call to Element, and generate:
+ -- We create a block to hold a variable declaration initialized with
+ -- a call to Element, and generate:
-- Cursor : Cursor_Type := First (Container);
-- while Has_Element (Cursor, Container) loop
@@ -4123,48 +4151,20 @@ package body Exp_Ch5 is
Defining_Identifier => Element,
Object_Definition => New_Occurrence_Of (Etype (Element_Op), Loc));
- if not Is_Constrained (Etype (Element_Op)) then
- Set_Expression (Elmt_Decl,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Element_Op, Loc),
- Parameter_Associations => New_List (
- Convert_To_Iterable_Type (Container, Loc),
- New_Occurrence_Of (Cursor, Loc))));
-
- Set_Statements (New_Loop,
- New_List
- (Make_Block_Statement (Loc,
- Declarations => New_List (Elmt_Decl),
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => Stats))));
-
- else
- Elmt_Ref :=
- Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Element, Loc),
- Expression =>
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Element_Op, Loc),
- Parameter_Associations => New_List (
- Convert_To_Iterable_Type (Container, Loc),
- New_Occurrence_Of (Cursor, Loc))));
-
- Prepend (Elmt_Ref, Stats);
-
- -- The element is assignable in the expanded code
-
- Set_Assignment_OK (Name (Elmt_Ref));
-
- -- The loop is rewritten as a block, to hold the element declaration
-
- New_Loop :=
- Make_Block_Statement (Loc,
- Declarations => New_List (Elmt_Decl),
+ Set_Expression (Elmt_Decl,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Element_Op, Loc),
+ Parameter_Associations => New_List (
+ Convert_To_Iterable_Type (Container, Loc),
+ New_Occurrence_Of (Cursor, Loc))));
+
+ Set_Statements (New_Loop,
+ New_List
+ (Make_Block_Statement (Loc,
+ Declarations => New_List (Elmt_Decl),
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (New_Loop)));
- end if;
+ Statements => Stats))));
-- The element is only modified in expanded code, so it appears as
-- unassigned to the warning machinery. We must suppress this spurious
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index b81216f..59704a4 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1803,6 +1803,7 @@ package body Exp_Ch6 is
and then Is_Entity_Name (Lhs)
and then
Present (Effective_Extra_Accessibility (Entity (Lhs)))
+ and then not No_Dynamic_Accessibility_Checks_Enabled (Lhs)
then
-- Copyback target is an Ada 2012 stand-alone object of an
-- anonymous access type.
@@ -2929,7 +2930,9 @@ package body Exp_Ch6 is
Name => New_Occurrence_Of (Lvl, Loc),
Expression =>
Accessibility_Level
- (Expression (Res_Assn), Dynamic_Level)));
+ (Expr => Expression (Res_Assn),
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False)));
end if;
end Expand_Branch;
@@ -3758,7 +3761,7 @@ package body Exp_Ch6 is
-- because the object has underlying discriminants with defaults.
if Present (Extra_Constrained (Formal)) then
- if Ekind (Etype (Prev)) in Private_Kind
+ if Is_Private_Type (Etype (Prev))
and then not Has_Discriminants (Base_Type (Etype (Prev)))
then
Add_Extra_Actual
@@ -3857,9 +3860,10 @@ package body Exp_Ch6 is
end if;
Add_Extra_Actual
- (Expr =>
- New_Occurrence_Of
- (Get_Dynamic_Accessibility (Parm_Ent), Loc),
+ (Expr => Accessibility_Level
+ (Expr => Parm_Ent,
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False),
EF => Extra_Accessibility (Formal));
end;
@@ -3890,15 +3894,20 @@ package body Exp_Ch6 is
Add_Extra_Actual
(Expr => Accessibility_Level
- (Expr => Expression (Parent (Entity (Prev))),
- Level => Dynamic_Level),
+ (Expr => Expression
+ (Parent (Entity (Prev))),
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False),
EF => Extra_Accessibility (Formal));
-- Normal case
else
Add_Extra_Actual
- (Expr => Accessibility_Level (Prev, Dynamic_Level),
+ (Expr => Accessibility_Level
+ (Expr => Prev,
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False),
EF => Extra_Accessibility (Formal));
end if;
end if;
@@ -4142,8 +4151,10 @@ package body Exp_Ch6 is
-- Otherwise get the level normally based on the call node
else
- Level := Accessibility_Level (Call_Node, Dynamic_Level);
-
+ Level := Accessibility_Level
+ (Expr => Call_Node,
+ Level => Dynamic_Level,
+ Allow_Alt_Model => False);
end if;
-- It may be possible that we are re-expanding an already
@@ -4902,7 +4913,7 @@ package body Exp_Ch6 is
-- Optimization, if the returned value (which is on the sec-stack) is
-- returned again, no need to copy/readjust/finalize, we can just pass
-- the value thru (see Expand_N_Simple_Return_Statement), and thus no
- -- attachment is needed
+ -- attachment is needed.
if Nkind (Parent (N)) = N_Simple_Return_Statement then
return;
@@ -5841,11 +5852,9 @@ package body Exp_Ch6 is
Name =>
New_Occurrence_Of (Alloc_Obj_Id, Loc),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Ref_Type, Loc),
- Expression =>
- New_Occurrence_Of (Obj_Acc_Formal, Loc)))),
+ Unchecked_Convert_To
+ (Ref_Type,
+ New_Occurrence_Of (Obj_Acc_Formal, Loc)))),
Elsif_Parts => New_List (
Make_Elsif_Part (Loc,
@@ -5986,11 +5995,9 @@ package body Exp_Ch6 is
Object_Definition =>
New_Occurrence_Of (Ref_Type, Loc),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Ref_Type, Loc),
- Expression =>
- New_Occurrence_Of (Obj_Acc_Formal, Loc)));
+ Unchecked_Convert_To
+ (Ref_Type,
+ New_Occurrence_Of (Obj_Acc_Formal, Loc)));
Insert_Before (Ret_Obj_Decl, Alloc_Obj_Decl);
@@ -6431,18 +6438,7 @@ package body Exp_Ch6 is
-- Returns_By_Ref flag is normally set when the subprogram is frozen but
-- subprograms with no specs are not frozen.
- declare
- Typ : constant Entity_Id := Etype (Spec_Id);
- Utyp : constant Entity_Id := Underlying_Type (Typ);
-
- begin
- if Is_Limited_View (Typ) then
- Set_Returns_By_Ref (Spec_Id);
-
- elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
- Set_Returns_By_Ref (Spec_Id);
- end if;
- end;
+ Compute_Returns_By_Ref (Spec_Id);
-- For a procedure, we add a return for all possible syntactic ends of
-- the subprogram.
@@ -7314,15 +7310,16 @@ package body Exp_Ch6 is
Set_Enclosing_Sec_Stack_Return (N);
- -- Optimize the case where the result is a function call. In this
- -- case the result is already on the secondary stack and no further
- -- processing is required except to set the By_Ref flag to ensure
- -- that gigi does not attempt an extra unnecessary copy. (Actually
- -- not just unnecessary but wrong in the case of a controlled type,
- -- where gigi does not know how to do a copy.)
+ -- Optimize the case where the result is a function call that also
+ -- returns on the secondary stack. In this case the result is already
+ -- on the secondary stack and no further processing is required
+ -- except to set the By_Ref flag to ensure that gigi does not attempt
+ -- an extra unnecessary copy. (Actually not just unnecessary but
+ -- wrong in the case of a controlled type, where gigi does not know
+ -- how to do a copy.)
- if Requires_Transient_Scope (Exp_Typ)
- and then Exp_Is_Function_Call
+ pragma Assert (Requires_Transient_Scope (R_Type));
+ if Exp_Is_Function_Call and then Requires_Transient_Scope (Exp_Typ)
then
Set_By_Ref (N);
@@ -7851,20 +7848,9 @@ package body Exp_Ch6 is
-- of the normal semantic analysis of the spec since the underlying
-- returned type may not be known yet (for private types).
- declare
- Typ : constant Entity_Id := Etype (Subp);
- Utyp : constant Entity_Id := Underlying_Type (Typ);
-
- begin
- if Is_Limited_View (Typ) then
- Set_Returns_By_Ref (Subp);
+ Compute_Returns_By_Ref (Subp);
- elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
- Set_Returns_By_Ref (Subp);
- end if;
- end;
-
- -- Wnen freezing a null procedure, analyze its delayed aspects now
+ -- When freezing a null procedure, analyze its delayed aspects now
-- because we may not have reached the end of the declarative list when
-- delayed aspects are normally analyzed. This ensures that dispatching
-- calls are properly rewritten when the generated _Postcondition
@@ -8234,10 +8220,6 @@ package body Exp_Ch6 is
return False;
end if;
- -- For now we test whether E denotes a function or access-to-function
- -- type whose result subtype is inherently limited. Later this test
- -- may be revised to allow composite nonlimited types.
-
if Ekind (E) in E_Function | E_Generic_Function
or else (Ekind (E) = E_Subprogram_Type
and then Etype (E) /= Standard_Void_Type)
@@ -8293,6 +8275,15 @@ package body Exp_Ch6 is
-- This may be a call to a protected function.
elsif Nkind (Name (Exp_Node)) = N_Selected_Component then
+ -- The selector in question might not have been analyzed due to a
+ -- previous error, so analyze it here to output the appropriate
+ -- error message instead of crashing when attempting to fetch its
+ -- entity.
+
+ if not Analyzed (Selector_Name (Name (Exp_Node))) then
+ Analyze (Selector_Name (Name (Exp_Node)));
+ end if;
+
Function_Id := Etype (Entity (Selector_Name (Name (Exp_Node))));
else
@@ -8525,12 +8516,10 @@ package body Exp_Ch6 is
Alloc_Form := Caller_Allocation;
Pool := Make_Null (No_Location);
- Return_Obj_Actual :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Result_Subt, Loc),
- Expression =>
- Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Return_Obj_Access, Loc)));
+ Return_Obj_Actual := Unchecked_Convert_To
+ (Result_Subt,
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Return_Obj_Access, Loc)));
-- When the result subtype is unconstrained, the function itself must
-- perform the allocation of the return object, so we pass parameters
@@ -8844,11 +8833,7 @@ package body Exp_Ch6 is
-- the caller's return object.
Add_Access_Actual_To_Build_In_Place_Call
- (Func_Call,
- Func_Id,
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Result_Subt, Loc),
- Expression => Relocate_Node (Lhs)));
+ (Func_Call, Func_Id, Unchecked_Convert_To (Result_Subt, Lhs));
-- Create an access type designating the function's result subtype
@@ -8872,11 +8857,7 @@ package body Exp_Ch6 is
-- Add a conversion if it's the wrong type
- if Etype (New_Expr) /= Ptr_Typ then
- New_Expr :=
- Make_Unchecked_Type_Conversion (Loc,
- New_Occurrence_Of (Ptr_Typ, Loc), New_Expr);
- end if;
+ New_Expr := Unchecked_Convert_To (Ptr_Typ, New_Expr);
Obj_Id := Make_Temporary (Loc, 'R', New_Expr);
Set_Etype (Obj_Id, Ptr_Typ);
@@ -9135,16 +9116,10 @@ package body Exp_Ch6 is
-- it to the access type of the callee's BIP_Object_Access formal.
Caller_Object :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of
- (Etype (Build_In_Place_Formal
- (Function_Id, BIP_Object_Access)),
- Loc),
- Expression =>
- New_Occurrence_Of
- (Build_In_Place_Formal (Encl_Func, BIP_Object_Access),
- Loc));
+ Unchecked_Convert_To
+ (Etype (Build_In_Place_Formal (Function_Id, BIP_Object_Access)),
+ New_Occurrence_Of
+ (Build_In_Place_Formal (Encl_Func, BIP_Object_Access), Loc));
-- In the definite case, add an implicit actual to the function call
-- that provides access to the declared object. An unchecked conversion
@@ -9152,10 +9127,8 @@ package body Exp_Ch6 is
-- the case where the object is declared with a class-wide type.
elsif Definite then
- Caller_Object :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Result_Subt, Loc),
- Expression => New_Occurrence_Of (Obj_Def_Id, Loc));
+ Caller_Object := Unchecked_Convert_To
+ (Result_Subt, New_Occurrence_Of (Obj_Def_Id, Loc));
-- When the function has a controlling result, an allocation-form
-- parameter must be passed indicating that the caller is allocating
@@ -9263,9 +9236,8 @@ package body Exp_Ch6 is
Constant_Present => True,
Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- New_Occurrence_Of (Ptr_Typ, Loc),
- Make_Reference (Loc, Relocate_Node (Func_Call))));
+ Unchecked_Convert_To
+ (Ptr_Typ, Make_Reference (Loc, Relocate_Node (Func_Call))));
else
Res_Decl :=
Make_Object_Declaration (Loc,
diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads
index 07a88c5..76cec4d 100644
--- a/gcc/ada/exp_ch6.ads
+++ b/gcc/ada/exp_ch6.ads
@@ -134,8 +134,11 @@ package Exp_Ch6 is
--
-- For inherently limited types in Ada 2005, True means that calls will
-- actually be build-in-place in all cases. For other types, build-in-place
- -- will be used when possible, but we need to make a copy at the call site
- -- in some cases, notably assignment statements.
+ -- will be used when possible, but we need to make a copy in some
+ -- cases. For example, for "X := F(...);" if F can see X, or if F can
+ -- propagate exceptions, we need to store its result in a temp in general,
+ -- and copy the temp into X. Also, for "return Global_Var;" Global_Var
+ -- needs to be copied into the function result object.
function Is_Build_In_Place_Function (E : Entity_Id) return Boolean;
-- Ada 2005 (AI-318-02): Returns True if E denotes a function, generic
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index a534370..f7807ac 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -131,11 +131,6 @@ package body Exp_Ch7 is
-- Transient Blocks and Finalization Management --
--------------------------------------------------
- function Find_Transient_Context (N : Node_Id) return Node_Id;
- -- Locate a suitable context for arbitrary node N which may need to be
- -- serviced by a transient scope. Return Empty if no suitable context is
- -- available.
-
procedure Insert_Actions_In_Scope_Around
(N : Node_Id;
Clean : Boolean;
@@ -155,9 +150,6 @@ package body Exp_Ch7 is
-- involves controlled objects or secondary stack usage, the corresponding
-- cleanup actions are performed at the end of the block.
- procedure Set_Node_To_Be_Wrapped (N : Node_Id);
- -- Set the field Node_To_Be_Wrapped of the current scope
-
procedure Store_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id);
-- Shared processing for Store_xxx_Actions_In_Scope
@@ -488,7 +480,7 @@ package body Exp_Ch7 is
Skip_Self : Boolean := False) return Node_Id;
-- Subsidiary to Make_Adjust_Call and Make_Final_Call. Given the entity of
-- routine [Deep_]Adjust or [Deep_]Finalize and an object parameter, create
- -- an adjust or finalization call. Wnen flag Skip_Self is set, the related
+ -- an adjust or finalization call. When flag Skip_Self is set, the related
-- action has an effect on the components only (if any).
function Make_Deep_Proc
@@ -5118,15 +5110,6 @@ package body Exp_Ch7 is
end if;
end Convert_View;
- -------------------------------
- -- CW_Or_Has_Controlled_Part --
- -------------------------------
-
- function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean is
- begin
- return Is_Class_Wide_Type (T) or else Needs_Finalization (T);
- end CW_Or_Has_Controlled_Part;
-
------------------------
-- Enclosing_Function --
------------------------
@@ -5160,37 +5143,47 @@ package body Exp_Ch7 is
(N : Node_Id;
Manage_Sec_Stack : Boolean)
is
- procedure Create_Transient_Scope (Constr : Node_Id);
- -- Place a new scope on the scope stack in order to service construct
- -- Constr. The new scope may also manage the secondary stack.
+ function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean;
+ -- Determine whether arbitrary Id denotes a package or subprogram [body]
+
+ function Find_Enclosing_Transient_Scope return Entity_Id;
+ -- Examine the scope stack looking for the nearest enclosing transient
+ -- scope within the innermost enclosing package or subprogram. Return
+ -- Empty if no such scope exists.
+
+ function Find_Transient_Context (N : Node_Id) return Node_Id;
+ -- Locate a suitable context for arbitrary node N which may need to be
+ -- serviced by a transient scope. Return Empty if no suitable context
+ -- is available.
procedure Delegate_Sec_Stack_Management;
-- Move the management of the secondary stack to the nearest enclosing
-- suitable scope.
- function Find_Enclosing_Transient_Scope return Entity_Id;
- -- Examine the scope stack looking for the nearest enclosing transient
- -- scope. Return Empty if no such scope exists.
-
- function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean;
- -- Determine whether arbitrary Id denotes a package or subprogram [body]
+ procedure Create_Transient_Scope (Context : Node_Id);
+ -- Place a new scope on the scope stack in order to service construct
+ -- Context. Context is the node found by Find_Transient_Context. The
+ -- new scope may also manage the secondary stack.
----------------------------
-- Create_Transient_Scope --
----------------------------
- procedure Create_Transient_Scope (Constr : Node_Id) is
+ procedure Create_Transient_Scope (Context : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Iter_Loop : Entity_Id;
- Trans_Scop : Entity_Id;
+ Trans_Scop : constant Entity_Id :=
+ New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
begin
- Trans_Scop := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
Set_Etype (Trans_Scop, Standard_Void_Type);
+ -- Push a new scope, and set its Node_To_Be_Wrapped and Is_Transient
+ -- fields.
+
Push_Scope (Trans_Scop);
- Set_Node_To_Be_Wrapped (Constr);
+ Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped := Context;
Set_Scope_Is_Transient;
-- The transient scope must also manage the secondary stack
@@ -5241,37 +5234,34 @@ package body Exp_Ch7 is
-----------------------------------
procedure Delegate_Sec_Stack_Management is
- Scop_Id : Entity_Id;
- Scop_Rec : Scope_Stack_Entry;
-
begin
for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
- Scop_Rec := Scope_Stack.Table (Index);
- Scop_Id := Scop_Rec.Entity;
-
- -- Prevent the search from going too far or within the scope space
- -- of another unit.
+ declare
+ Scope : Scope_Stack_Entry renames Scope_Stack.Table (Index);
+ begin
+ -- Prevent the search from going too far or within the scope
+ -- space of another unit.
- if Scop_Id = Standard_Standard then
- return;
+ if Scope.Entity = Standard_Standard then
+ return;
- -- No transient scope should be encountered during the traversal
- -- because Establish_Transient_Scope should have already handled
- -- this case.
+ -- No transient scope should be encountered during the
+ -- traversal because Establish_Transient_Scope should have
+ -- already handled this case.
- elsif Scop_Rec.Is_Transient then
- pragma Assert (False);
- return;
+ elsif Scope.Is_Transient then
+ raise Program_Error;
- -- The construct which requires secondary stack management is
- -- always enclosed by a package or subprogram scope.
+ -- The construct that requires secondary stack management is
+ -- always enclosed by a package or subprogram scope.
- elsif Is_Package_Or_Subprogram (Scop_Id) then
- Set_Uses_Sec_Stack (Scop_Id);
- Check_Restriction (No_Secondary_Stack, N);
+ elsif Is_Package_Or_Subprogram (Scope.Entity) then
+ Set_Uses_Sec_Stack (Scope.Entity);
+ Check_Restriction (No_Secondary_Stack, N);
- return;
- end if;
+ return;
+ end if;
+ end;
end loop;
-- At this point no suitable scope was found. This should never occur
@@ -5286,30 +5276,198 @@ package body Exp_Ch7 is
------------------------------------
function Find_Enclosing_Transient_Scope return Entity_Id is
- Scop_Id : Entity_Id;
- Scop_Rec : Scope_Stack_Entry;
-
begin
for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
- Scop_Rec := Scope_Stack.Table (Index);
- Scop_Id := Scop_Rec.Entity;
-
- -- Prevent the search from going too far or within the scope space
- -- of another unit.
+ declare
+ Scope : Scope_Stack_Entry renames Scope_Stack.Table (Index);
+ begin
+ -- Prevent the search from going too far or within the scope
+ -- space of another unit.
- if Scop_Id = Standard_Standard
- or else Is_Package_Or_Subprogram (Scop_Id)
- then
- exit;
+ if Scope.Entity = Standard_Standard
+ or else Is_Package_Or_Subprogram (Scope.Entity)
+ then
+ exit;
- elsif Scop_Rec.Is_Transient then
- return Scop_Id;
- end if;
+ elsif Scope.Is_Transient then
+ return Scope.Entity;
+ end if;
+ end;
end loop;
return Empty;
end Find_Enclosing_Transient_Scope;
+ ----------------------------
+ -- Find_Transient_Context --
+ ----------------------------
+
+ function Find_Transient_Context (N : Node_Id) return Node_Id is
+ Curr : Node_Id := N;
+ Prev : Node_Id := Empty;
+
+ begin
+ while Present (Curr) loop
+ case Nkind (Curr) is
+
+ -- Declarations
+
+ -- Declarations act as a boundary for a transient scope even if
+ -- they are not wrapped, see Wrap_Transient_Declaration.
+
+ when N_Object_Declaration
+ | N_Object_Renaming_Declaration
+ | N_Subtype_Declaration
+ =>
+ return Curr;
+
+ -- Statements
+
+ -- Statements and statement-like constructs act as a boundary
+ -- for a transient scope.
+
+ when N_Accept_Alternative
+ | N_Attribute_Definition_Clause
+ | N_Case_Statement
+ | N_Case_Statement_Alternative
+ | N_Code_Statement
+ | N_Delay_Alternative
+ | N_Delay_Until_Statement
+ | N_Delay_Relative_Statement
+ | N_Discriminant_Association
+ | N_Elsif_Part
+ | N_Entry_Body_Formal_Part
+ | N_Exit_Statement
+ | N_If_Statement
+ | N_Iteration_Scheme
+ | N_Terminate_Alternative
+ =>
+ pragma Assert (Present (Prev));
+ return Prev;
+
+ when N_Assignment_Statement =>
+ return Curr;
+
+ when N_Entry_Call_Statement
+ | N_Procedure_Call_Statement
+ =>
+ -- When an entry or procedure call acts as the alternative
+ -- of a conditional or timed entry call, the proper context
+ -- is that of the alternative.
+
+ if Nkind (Parent (Curr)) = N_Entry_Call_Alternative
+ and then Nkind (Parent (Parent (Curr))) in
+ N_Conditional_Entry_Call | N_Timed_Entry_Call
+ then
+ return Parent (Parent (Curr));
+
+ -- General case for entry or procedure calls
+
+ else
+ return Curr;
+ end if;
+
+ when N_Pragma =>
+
+ -- Pragma Check is not a valid transient context in
+ -- GNATprove mode because the pragma must remain unchanged.
+
+ if GNATprove_Mode
+ and then Get_Pragma_Id (Curr) = Pragma_Check
+ then
+ return Empty;
+
+ -- General case for pragmas
+
+ else
+ return Curr;
+ end if;
+
+ when N_Raise_Statement =>
+ return Curr;
+
+ when N_Simple_Return_Statement =>
+
+ -- A return statement is not a valid transient context when
+ -- the function itself requires transient scope management
+ -- because the result will be reclaimed too early.
+
+ if Requires_Transient_Scope (Etype
+ (Return_Applies_To (Return_Statement_Entity (Curr))))
+ then
+ return Empty;
+
+ -- General case for return statements
+
+ else
+ return Curr;
+ end if;
+
+ -- Special
+
+ when N_Attribute_Reference =>
+ if Is_Procedure_Attribute_Name (Attribute_Name (Curr)) then
+ return Curr;
+ end if;
+
+ -- An Ada 2012 iterator specification is not a valid context
+ -- because Analyze_Iterator_Specification already employs
+ -- special processing for it.
+
+ when N_Iterator_Specification =>
+ return Empty;
+
+ when N_Loop_Parameter_Specification =>
+
+ -- An iteration scheme is not a valid context because
+ -- routine Analyze_Iteration_Scheme already employs
+ -- special processing.
+
+ if Nkind (Parent (Curr)) = N_Iteration_Scheme then
+ return Empty;
+ else
+ return Parent (Curr);
+ end if;
+
+ -- Termination
+
+ -- The following nodes represent "dummy contexts" which do not
+ -- need to be wrapped.
+
+ when N_Component_Declaration
+ | N_Discriminant_Specification
+ | N_Parameter_Specification
+ =>
+ return Empty;
+
+ -- If the traversal leaves a scope without having been able to
+ -- find a construct to wrap, something is going wrong, but this
+ -- can happen in error situations that are not detected yet
+ -- (such as a dynamic string in a pragma Export).
+
+ when N_Block_Statement
+ | N_Entry_Body
+ | N_Package_Body
+ | N_Package_Declaration
+ | N_Protected_Body
+ | N_Subprogram_Body
+ | N_Task_Body
+ =>
+ return Empty;
+
+ -- Default
+
+ when others =>
+ null;
+ end case;
+
+ Prev := Curr;
+ Curr := Parent (Curr);
+ end loop;
+
+ return Empty;
+ end Find_Transient_Context;
+
------------------------------
-- Is_Package_Or_Subprogram --
------------------------------
@@ -5332,8 +5490,8 @@ package body Exp_Ch7 is
-- Start of processing for Establish_Transient_Scope
begin
- -- Do not create a new transient scope if there is an existing transient
- -- scope on the stack.
+ -- Do not create a new transient scope if there is already an enclosing
+ -- transient scope within the innermost enclosing package or subprogram.
if Present (Trans_Id) then
@@ -5347,9 +5505,8 @@ package body Exp_Ch7 is
return;
end if;
- -- At this point it is known that the scope stack is free of transient
- -- scopes. Locate the proper construct which must be serviced by a new
- -- transient scope.
+ -- Find the construct that must be serviced by a new transient scope, if
+ -- it exists.
Context := Find_Transient_Context (N);
@@ -5959,208 +6116,6 @@ package body Exp_Ch7 is
end if;
end Expand_N_Package_Declaration;
- ----------------------------
- -- Find_Transient_Context --
- ----------------------------
-
- function Find_Transient_Context (N : Node_Id) return Node_Id is
- Curr : Node_Id;
- Prev : Node_Id;
-
- begin
- Curr := N;
- Prev := Empty;
- while Present (Curr) loop
- case Nkind (Curr) is
-
- -- Declarations
-
- -- Declarations act as a boundary for a transient scope even if
- -- they are not wrapped, see Wrap_Transient_Declaration.
-
- when N_Object_Declaration
- | N_Object_Renaming_Declaration
- | N_Subtype_Declaration
- =>
- return Curr;
-
- -- Statements
-
- -- Statements and statement-like constructs act as a boundary for
- -- a transient scope.
-
- when N_Accept_Alternative
- | N_Attribute_Definition_Clause
- | N_Case_Statement
- | N_Case_Statement_Alternative
- | N_Code_Statement
- | N_Delay_Alternative
- | N_Delay_Until_Statement
- | N_Delay_Relative_Statement
- | N_Discriminant_Association
- | N_Elsif_Part
- | N_Entry_Body_Formal_Part
- | N_Exit_Statement
- | N_If_Statement
- | N_Iteration_Scheme
- | N_Terminate_Alternative
- =>
- pragma Assert (Present (Prev));
- return Prev;
-
- when N_Assignment_Statement =>
- return Curr;
-
- when N_Entry_Call_Statement
- | N_Procedure_Call_Statement
- =>
- -- When an entry or procedure call acts as the alternative of a
- -- conditional or timed entry call, the proper context is that
- -- of the alternative.
-
- if Nkind (Parent (Curr)) = N_Entry_Call_Alternative
- and then Nkind (Parent (Parent (Curr))) in
- N_Conditional_Entry_Call | N_Timed_Entry_Call
- then
- return Parent (Parent (Curr));
-
- -- General case for entry or procedure calls
-
- else
- return Curr;
- end if;
-
- when N_Pragma =>
-
- -- Pragma Check is not a valid transient context in GNATprove
- -- mode because the pragma must remain unchanged.
-
- if GNATprove_Mode
- and then Get_Pragma_Id (Curr) = Pragma_Check
- then
- return Empty;
-
- -- General case for pragmas
-
- else
- return Curr;
- end if;
-
- when N_Raise_Statement =>
- return Curr;
-
- when N_Simple_Return_Statement =>
-
- -- A return statement is not a valid transient context when the
- -- function itself requires transient scope management because
- -- the result will be reclaimed too early.
-
- if Requires_Transient_Scope (Etype
- (Return_Applies_To (Return_Statement_Entity (Curr))))
- then
- return Empty;
-
- -- General case for return statements
-
- else
- return Curr;
- end if;
-
- -- Special
-
- when N_Attribute_Reference =>
- if Is_Procedure_Attribute_Name (Attribute_Name (Curr)) then
- return Curr;
- end if;
-
- -- An Ada 2012 iterator specification is not a valid context
- -- because Analyze_Iterator_Specification already employs special
- -- processing for it.
-
- when N_Iterator_Specification =>
- return Empty;
-
- when N_Loop_Parameter_Specification =>
-
- -- An iteration scheme is not a valid context because routine
- -- Analyze_Iteration_Scheme already employs special processing.
-
- if Nkind (Parent (Curr)) = N_Iteration_Scheme then
- return Empty;
- else
- return Parent (Curr);
- end if;
-
- -- Termination
-
- -- The following nodes represent "dummy contexts" which do not
- -- need to be wrapped.
-
- when N_Component_Declaration
- | N_Discriminant_Specification
- | N_Parameter_Specification
- =>
- return Empty;
-
- -- If the traversal leaves a scope without having been able to
- -- find a construct to wrap, something is going wrong, but this
- -- can happen in error situations that are not detected yet (such
- -- as a dynamic string in a pragma Export).
-
- when N_Block_Statement
- | N_Entry_Body
- | N_Package_Body
- | N_Package_Declaration
- | N_Protected_Body
- | N_Subprogram_Body
- | N_Task_Body
- =>
- return Empty;
-
- -- Default
-
- when others =>
- null;
- end case;
-
- Prev := Curr;
- Curr := Parent (Curr);
- end loop;
-
- return Empty;
- end Find_Transient_Context;
-
- ----------------------------------
- -- Has_New_Controlled_Component --
- ----------------------------------
-
- function Has_New_Controlled_Component (E : Entity_Id) return Boolean is
- Comp : Entity_Id;
-
- begin
- if not Is_Tagged_Type (E) then
- return Has_Controlled_Component (E);
- elsif not Is_Derived_Type (E) then
- return Has_Controlled_Component (E);
- end if;
-
- Comp := First_Component (E);
- while Present (Comp) loop
- if Chars (Comp) = Name_uParent then
- null;
-
- elsif Scope (Original_Record_Component (Comp)) = E
- and then Needs_Finalization (Etype (Comp))
- then
- return True;
- end if;
-
- Next_Component (Comp);
- end loop;
-
- return False;
- end Has_New_Controlled_Component;
-
---------------------------------
-- Has_Simple_Protected_Object --
---------------------------------
@@ -8171,7 +8126,7 @@ package body Exp_Ch7 is
-- end if;
-- ...
- -- When Deep_Adjust is invokes for field _parent, a value of False is
+ -- When Deep_Adjust is invoked for field _parent, a value of False is
-- provided for the flag:
-- Deep_Adjust (Obj._parent, False);
@@ -9389,7 +9344,7 @@ package body Exp_Ch7 is
Dope_Id : Entity_Id;
begin
- -- Ensure that Ptr_Typ a thin pointer, generate:
+ -- Ensure that Ptr_Typ is a thin pointer; generate:
-- for Ptr_Typ'Size use System.Address'Size;
Append_To (Decls,
@@ -9931,15 +9886,6 @@ package body Exp_Ch7 is
end Node_To_Be_Wrapped;
----------------------------
- -- Set_Node_To_Be_Wrapped --
- ----------------------------
-
- procedure Set_Node_To_Be_Wrapped (N : Node_Id) is
- begin
- Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped := N;
- end Set_Node_To_Be_Wrapped;
-
- ----------------------------
-- Store_Actions_In_Scope --
----------------------------
diff --git a/gcc/ada/exp_ch7.ads b/gcc/ada/exp_ch7.ads
index 62fdb8a..ef1bf67 100644
--- a/gcc/ada/exp_ch7.ads
+++ b/gcc/ada/exp_ch7.ads
@@ -153,17 +153,6 @@ package Exp_Ch7 is
-- triggered by an abort, E_Id denotes the defining identifier of a local
-- exception occurrence, Raised_Id is the entity of a local boolean flag.
- function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean;
- -- True if T is a class-wide type, or if it has controlled parts ("part"
- -- means T or any of its subcomponents). Same as Needs_Finalization, except
- -- when pragma Restrictions (No_Finalization) applies, in which case we
- -- know that class-wide objects do not contain controlled parts.
-
- function Has_New_Controlled_Component (E : Entity_Id) return Boolean;
- -- E is a type entity. Give the same result as Has_Controlled_Component
- -- except for tagged extensions where the result is True only if the
- -- latest extension contains a controlled component.
-
function Make_Adjust_Call
(Obj_Ref : Node_Id;
Typ : Entity_Id;
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 6b1e284..427b430 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -6510,14 +6510,12 @@ package body Exp_Ch9 is
-- Task_Id (Tasknm._disp_get_task_id)
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RO_ST_Task_Id), Loc),
- Expression =>
- Make_Selected_Component (Loc,
- Prefix => New_Copy_Tree (Tasknm),
- Selector_Name =>
- Make_Identifier (Loc, Name_uDisp_Get_Task_Id)))));
+ Unchecked_Convert_To
+ (RTE (RO_ST_Task_Id),
+ Make_Selected_Component (Loc,
+ Prefix => New_Copy_Tree (Tasknm),
+ Selector_Name =>
+ Make_Identifier (Loc, Name_uDisp_Get_Task_Id)))));
else
Append_To (Component_Associations (Aggr),
@@ -7242,10 +7240,9 @@ package body Exp_Ch9 is
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Bnn, Loc),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Communication_Block), Loc),
- Expression => Make_Identifier (Loc, Name_uD))));
+ Unchecked_Convert_To
+ (RTE (RE_Communication_Block),
+ Make_Identifier (Loc, Name_uD))));
-- Generate:
-- _Disp_Asynchronous_Select (<object>, S, P'Address, D, B);
@@ -7361,10 +7358,9 @@ package body Exp_Ch9 is
Name =>
New_Occurrence_Of (Bnn, Loc),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Communication_Block), Loc),
- Expression => Make_Identifier (Loc, Name_uD))));
+ Unchecked_Convert_To
+ (RTE (RE_Communication_Block),
+ Make_Identifier (Loc, Name_uD))));
-- Generate:
-- _Disp_Asynchronous_Select (<object>, S, P'Address, D, B);
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index ed5ae43..bfc3b33 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -655,10 +655,10 @@ package body Exp_Dbug is
Has_Suffix := True;
- -- Fixed-point case: generate GNAT encodings when asked to
+ -- Generate GNAT encodings when asked to for fixed-point case
- if Is_Fixed_Point_Type (E)
- and then GNAT_Encodings = DWARF_GNAT_Encodings_All
+ if GNAT_Encodings = DWARF_GNAT_Encodings_All
+ and then Is_Fixed_Point_Type (E)
then
Get_External_Name (E, True, "XF_");
Add_Real_To_Buffer (Delta_Value (E));
@@ -668,10 +668,9 @@ package body Exp_Dbug is
Add_Real_To_Buffer (Small_Value (E));
end if;
- -- Discrete case where bounds do not match size. Not necessary if we can
- -- emit standard DWARF.
+ -- Likewise for discrete case where bounds do not match size
- elsif GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal
+ elsif GNAT_Encodings = DWARF_GNAT_Encodings_All
and then Is_Discrete_Type (E)
and then not Bounds_Match_Size (E)
then
diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads
index 5e1bc91..09921f0 100644
--- a/gcc/ada/exp_dbug.ads
+++ b/gcc/ada/exp_dbug.ads
@@ -23,9 +23,11 @@
-- --
------------------------------------------------------------------------------
--- Expand routines for generation of special declarations used by the
--- debugger. In accordance with the Dwarf 2.2 specification, certain
--- type names are encoded to provide information to the debugger.
+-- Expand routines for the generation of special declarations used by the
+-- debugger. In accordance with the DWARF specification, certain type names
+-- may also be encoded to provide additional information to the debugger, but
+-- this practice is being deprecated and some encodings described below are no
+-- longer generated by default (they are marked OBSOLETE).
with Namet; use Namet;
with Types; use Types;
@@ -496,53 +498,104 @@ package Exp_Dbug is
-- corresponding positive value followed by a lower case m for minus to
-- indicate that the value is negative (e.g. 2m for -2).
- -------------------------
- -- Type Name Encodings --
- -------------------------
+ ------------------------
+ -- Encapsulated Types --
+ ------------------------
+
+ -- In some cases, the compiler may encapsulate a type by wrapping it in a
+ -- record. For example, this is used when a size or alignment specification
+ -- requires a larger type. Consider:
+
+ -- type x is mod 2 ** 64;
+ -- for x'size use 256;
+
+ -- In this case, the compiler generates a record type x___PAD, which has
+ -- a single field whose name is F. This single field is 64-bit long and
+ -- contains the actual value. This kind of padding is used when the logical
+ -- value to be stored is shorter than the object in which it is allocated.
+
+ -- A similar encapsulation is done for some packed array types, in which
+ -- case the record type is x___JM and the field name is OBJECT. This is
+ -- used in the case of a packed array stored using modular representation
+ -- (see the section on representation of packed array objects). In this
+ -- case the wrapping is used to achieve correct positioning of the packed
+ -- array value (left/right justified in its field depending on endianness).
+
+ -- When the debugger sees an object of a type whose name has a suffix of
+ -- ___PAD or ___JM, the type will be a record containing a single field,
+ -- and the name of that field will be all upper case. In this case, it
+ -- should look inside to get the value of the inner field, and neither
+ -- the outer structure name, nor the field name should appear when the
+ -- value is printed.
+
+ -- Similarly, when the debugger sees a record named REP being the type of
+ -- a field inside another record type, it should treat the fields inside
+ -- REP as being part of the outer record (this REP field is only present
+ -- for code generation purposes). The REP record should not appear in the
+ -- values printed by the debugger.
+
+ --------------------
+ -- Implicit Types --
+ --------------------
+
+ -- The compiler creates implicit type names in many situations where a
+ -- type is present semantically, but no specific name is present. For
+ -- example:
+
+ -- S : Integer range M .. N;
+
+ -- Here the subtype of S is not integer, but rather an anonymous subtype
+ -- of Integer. Where possible, the compiler generates names for such
+ -- anonymous types that are related to the type from which the subtype
+ -- is obtained as follows:
+
+ -- T name suffix
+
+ -- where name is the name from which the subtype is obtained, using
+ -- lower case letters and underscores, and suffix starts with an upper
+ -- case letter. For example the name for the above declaration might be:
+
+ -- TintegerS4b
+
+ -- If the debugger is asked to give the type of an entity and the type
+ -- has the form T name suffix, it is probably appropriate to just use
+ -- "name" in the response since this is what is meaningful to the
+ -- programmer.
+
+ -------------------
+ -- Modular Types --
+ -------------------
+
+ -- A type declared
+
+ -- type x is mod N;
+
+ -- is encoded as a subrange of an unsigned base type with lower bound zero
+ -- and upper bound N - 1. Thus we give these types a somewhat nonstandard
+ -- interpretation: the standard interpretation would not, in general, imply
+ -- that arithmetic operations on type x are performed modulo N (especially
+ -- not when N is not a power of 2).
+
+ --------------------------------------
+ -- Tagged Types and Type Extensions --
+ --------------------------------------
+
+ -- A type D derived from a tagged type P has a field named "_parent" of
+ -- type P that contains its inherited fields. The type of this field is
+ -- usually P, but may be a more distant ancestor, if P is a null extension
+ -- of that type.
+
+ -- The type tag of a tagged type is a field named "_tag" of a pointer type.
+ -- If the type is derived from another tagged type, its _tag field is found
+ -- in its _parent field.
+
+ ------------------------------------
+ -- Type Name Encodings (OBSOLETE) --
+ ------------------------------------
-- In the following typ is the name of the type as normally encoded by the
-- debugger rules, i.e. a non-qualified name, all in lower case, with
- -- standard encoding of upper half and wide characters
-
- ------------------------
- -- Encapsulated Types --
- ------------------------
-
- -- In some cases, the compiler encapsulates a type by wrapping it in a
- -- structure. For example, this is used when a size or alignment
- -- specification requires a larger type. Consider:
-
- -- type y is mod 2 ** 64;
- -- for y'size use 256;
-
- -- In this case the compile generates a structure type y___PAD, which
- -- has a single field whose name is F. This single field is 64 bits
- -- long and contains the actual value. This kind of padding is used
- -- when the logical value to be stored is shorter than the object in
- -- which it is allocated. For example if a size clause is used to set
- -- a size of 256 for a signed integer value, then a typical choice is
- -- to wrap a 64-bit integer in a 256 bit PAD structure.
-
- -- A similar encapsulation is done for some packed array types, in which
- -- case the structure type is y___JM and the field name is OBJECT.
- -- This is used in the case of a packed array stored using modular
- -- representation (see section on representation of packed array
- -- objects). In this case the JM wrapping is used to achieve correct
- -- positioning of the packed array value (left or right justified in its
- -- field depending on endianness.
-
- -- When the debugger sees an object of a type whose name has a suffix of
- -- ___PAD or ___JM, the type will be a record containing a single field,
- -- and the name of that field will be all upper case. In this case, it
- -- should look inside to get the value of the inner field, and neither
- -- the outer structure name, nor the field name should appear when the
- -- value is printed.
-
- -- When the debugger sees a record named REP being a field inside
- -- another record, it should treat the fields inside REP as being part
- -- of the outer record (this REP field is only present for code
- -- generation purposes). The REP record should not appear in the values
- -- printed by the debugger.
+ -- standard encoding of upper half and wide characters.
-----------------------
-- Fixed-Point Types --
@@ -613,22 +666,6 @@ package Exp_Dbug is
-- or compile time known values, with the encoding first for the lower
-- bound, then for the upper bound, as previously described.
- -------------------
- -- Modular Types --
- -------------------
-
- -- A type declared
-
- -- type x is mod N;
-
- -- Is encoded as a subrange of an unsigned base type with lower bound
- -- zero and upper bound N. That is, there is no name encoding. We use
- -- the standard encodings provided by the debugging format. Thus we
- -- give these types a non-standard interpretation: the standard
- -- interpretation of our encoding would not, in general, imply that
- -- arithmetic on type x was to be performed modulo N (especially not
- -- when N is not a power of 2).
-
------------------
-- Biased Types --
------------------
@@ -887,34 +924,6 @@ package Exp_Dbug is
-- redundantly, particularly in the fixed-point case, but this
-- information can in any case be ignored by the debugger.
- ----------------------------
- -- Note on Implicit Types --
- ----------------------------
-
- -- The compiler creates implicit type names in many situations where a
- -- type is present semantically, but no specific name is present. For
- -- example:
-
- -- S : Integer range M .. N;
-
- -- Here the subtype of S is not integer, but rather an anonymous subtype
- -- of Integer. Where possible, the compiler generates names for such
- -- anonymous types that are related to the type from which the subtype
- -- is obtained as follows:
-
- -- T name suffix
-
- -- where name is the name from which the subtype is obtained, using
- -- lower case letters and underscores, and suffix starts with an upper
- -- case letter. For example the name for the above declaration might be:
-
- -- TintegerS4b
-
- -- If the debugger is asked to give the type of an entity and the type
- -- has the form T name suffix, it is probably appropriate to just use
- -- "name" in the response since this is what is meaningful to the
- -- programmer.
-
-------------------------------------------------
-- Subprograms for Handling Encoded Type Names --
-------------------------------------------------
@@ -1062,51 +1071,6 @@ package Exp_Dbug is
-- debug declaration, then Empty is returned. This function also takes care
-- of setting Materialize_Entity on the renamed entity where required.
- ---------------------------
- -- Packed Array Encoding --
- ---------------------------
-
- -- For every constrained packed array, two types are created, and both
- -- appear in the debugging output:
-
- -- The original declared array type is a perfectly normal array type, and
- -- its index bounds indicate the original bounds of the array.
-
- -- The corresponding packed array type, which may be a modular type, or
- -- may be an array of bytes type (see Exp_Pakd for full details). This is
- -- the type that is actually used in the generated code and for debugging
- -- information for all objects of the packed type.
-
- -- The name of the corresponding packed array type is:
-
- -- ttt___XPnnn
-
- -- where
-
- -- ttt is the name of the original declared array
- -- nnn is the component size in bits (1-31)
-
- -- Note that if the packed array is not bit-packed, the name will simply
- -- be tttP.
-
- -- When the debugger sees that an object is of a type that is encoded in
- -- this manner, it can use the original type to determine the bounds and
- -- the component type, and the component size to determine the packing
- -- details.
-
- -- For an unconstrained packed array, the corresponding packed array type
- -- is neither used in the generated code nor for debugging information,
- -- only the original type is used. In order to convey the packing in the
- -- debugging information, the compiler generates the associated fat- and
- -- thin-pointer types (see the Pointers to Unconstrained Array section
- -- below) using the name of the corresponding packed array type as the
- -- base name, i.e. ttt___XPnnn___XUP and ttt___XPnnn___XUT respectively.
-
- -- When the debugger sees that an object is of a type that is encoded in
- -- this manner, it can use the type of the fields to determine the bounds
- -- and the component type, and the component size to determine the packing
- -- details.
-
-------------------------------------------
-- Packed Array Representation in Memory --
-------------------------------------------
@@ -1204,6 +1168,51 @@ package Exp_Dbug is
-- would mean that an assignment such as a := above would require shifts
-- when one value is in a register and the other value is in memory.
+ -------------------------------------------
+ -- Packed Array Name Encoding (OBSOLETE) --
+ -------------------------------------------
+
+ -- For every constrained packed array, two types are created, and both
+ -- appear in the debugging output:
+
+ -- The original declared array type is a perfectly normal array type, and
+ -- its index bounds indicate the original bounds of the array.
+
+ -- The corresponding packed array type, which may be a modular type, or
+ -- may be an array of bytes type (see Exp_Pakd for full details). This is
+ -- the type that is actually used in the generated code and for debugging
+ -- information for all objects of the packed type.
+
+ -- The name of the corresponding packed array type is:
+
+ -- ttt___XPnnn
+
+ -- where
+
+ -- ttt is the name of the original declared array
+ -- nnn is the component size in bits (1-31)
+
+ -- Note that if the packed array is not bit-packed, the name will simply
+ -- be tttP.
+
+ -- When the debugger sees that an object is of a type that is encoded in
+ -- this manner, it can use the original type to determine the bounds and
+ -- the component type, and the component size to determine the packing
+ -- details.
+
+ -- For an unconstrained packed array, the corresponding packed array type
+ -- is neither used in the generated code nor for debugging information,
+ -- only the original type is used. In order to convey the packing in the
+ -- debugging information, the compiler generates the associated fat- and
+ -- thin-pointer types (see the Pointers to Unconstrained Array section
+ -- below) using the name of the corresponding packed array type as the
+ -- base name, i.e. ttt___XPnnn___XUP and ttt___XPnnn___XUT respectively.
+
+ -- When the debugger sees that an object is of a type that is encoded in
+ -- this manner, it can use the type of the fields to determine the bounds
+ -- and the component type, and the component size to determine the packing
+ -- details.
+
------------------------------------------------------
-- Subprograms for Handling Packed Array Type Names --
------------------------------------------------------
@@ -1219,58 +1228,67 @@ package Exp_Dbug is
-- Pointers to Unconstrained Arrays --
--------------------------------------
- -- There are two kinds of pointers to arrays. The debugger can tell which
- -- format is in use by the form of the type of the pointer.
+ -- There are two kinds of pointer to unconstrained arrays. The debugger can
+ -- tell which format is in use by the form of the type of the pointer.
-- Fat Pointers
- -- Fat pointers are represented as a struct with two fields. This
- -- struct has two distinguished field names:
+ -- Fat pointers are represented as a structure with two fields. This
+ -- structure has two distinguished field names:
-- P_ARRAY is a pointer to the array type. The name of this type is
- -- the unconstrained type followed by "___XUA". This array will have
- -- bounds which are the discriminants, and hence are unparsable, but
- -- will give the number of subscripts and the component type.
+ -- the unconstrained type followed by "___XUA". The bounds of this
+ -- array will be obtained through dereferences of P_BOUNDS below.
- -- P_BOUNDS is a pointer to a struct, the name of whose type is the
- -- unconstrained array name followed by "___XUB" and which has
- -- fields of the form
+ -- P_BOUNDS is a pointer to a structure. The name of this type is
+ -- the unconstrained array name followed by "___XUB" and it has
+ -- fields of the form:
-- LBn (n a decimal integer) lower bound of n'th dimension
-- UBn (n a decimal integer) upper bound of n'th dimension
- -- The bounds may be any integral type. In the case of an enumeration
- -- type, Enum_Rep values are used.
+ -- The bounds may be of any integral type. In the case of enumeration
+ -- types, Enum_Rep values are used.
+
+ -- For a given unconstrained array type, the compiler will generate a
+ -- fat pointer type whose name is the name of the array type, and use
+ -- it to represent the array type itself in the debugging information.
- -- For a given unconstrained array type, the compiler will generate one
- -- fat-pointer type whose name is "arr___XUP", where "arr" is the name
- -- of the array type, and use it to represent the array type itself in
- -- the debugging information.
+ -- This name was historically followed by "___XUP" (OBSOLETE).
-- For each pointer to this unconstrained array type, the compiler will
- -- generate a typedef that points to the above "arr___XUP" fat-pointer
- -- type. As a consequence, when it comes to fat-pointer types:
+ -- generate a typedef that points to the above fat pointer type. As a
+ -- consequence, when it comes to fat pointer types:
- -- 1. The type name is given by the typedef
+ -- 1. The type name is given by the typedef, if any
-- 2. If the debugger is asked to output the type, the appropriate
- -- form is "access arr", except if the type name is "arr___XUP"
- -- for which it is the array definition.
+ -- form is "access arr" if there is the typedef, otherwise it is
+ -- the array definition.
-- Thin Pointers
-- The value of a thin pointer is a pointer to the second field of a
+ -- structure with two fields. The first field of the structure is of
+ -- the type ___XUB described for fat pointer types above. The second
+ -- field of the structure contains the actual array.
+
+ -- Thin pointers are represented as a regular pointer to array in the
+ -- debugging information. The bounds of this array will be the contents
+ -- of the first field above obtained through (shifted) dereferences.
+
+ -- Thin Pointers (OBSOLETE)
+
+ -- The value of a thin pointer is a pointer to the second field of a
-- structure with two fields. The name of this structure's type is
-- "arr___XUT", where "arr" is the name of the unconstrained array
- -- type. Even though it actually points into middle of this structure,
- -- the thin pointer's type in debugging information is
- -- pointer-to-arr___XUT.
+ -- type. Even though it points into the middle of this structure,
+ -- the type in the debugging information is pointer to structure.
- -- The first field of arr___XUT is named BOUNDS, and has a type named
- -- arr___XUB, with the structure described for such types in fat
- -- pointers, as described above.
+ -- The first field of the structure is named BOUNDS and is of the type
+ -- ___XUB described for fat pointer types above.
- -- The second field of arr___XUT is named ARRAY, and contains the
+ -- The second field of the structure is named ARRAY, and contains the
-- actual array. Because this array has a dynamic size, determined by
-- the BOUNDS field that precedes it, all of the information about
-- arr___XUT is encoded in a parallel type named arr___XUT___XVE, with
@@ -1279,19 +1297,6 @@ package Exp_Dbug is
-- type in this case is named arr___XUA and only its element type is
-- meaningful, just as described for fat pointers.
- --------------------------------------
- -- Tagged Types and Type Extensions --
- --------------------------------------
-
- -- A type C derived from a tagged type P has a field named "_parent" of
- -- type P that contains its inherited fields. The type of this field is
- -- usually P (encoded as usual if it has a dynamic size), but may be a more
- -- distant ancestor, if P is a null extension of that type.
-
- -- The type tag of a tagged type is a field named _tag, of type void*. If
- -- the type is derived from another tagged type, its _tag field is found in
- -- its _parent field.
-
-----------------------------
-- Variant Record Encoding --
-----------------------------
@@ -1311,8 +1316,7 @@ package Exp_Dbug is
-- union, in which each member of the union corresponds to one variant.
-- However, unlike a C union, the size of the type may be variable even if
-- each of the components are fixed size, since it includes a computation
- -- of which variant is present. In that case, it will be encoded as above
- -- and a type with the suffix "___XVN___XVU" will be present.
+ -- of which variant is present.
-- The name of the union member is encoded to indicate the choices, and
-- is a string given by the following grammar:
@@ -1335,9 +1339,7 @@ package Exp_Dbug is
-- to the use of the Enum_Rep attribute).
-- The type of the inner record is given by the name of the union type (as
- -- above) concatenated with the above string. Since that type may itself be
- -- variable-sized, it may also be encoded as above with a new type with a
- -- further suffix of "___XVU".
+ -- above) concatenated with the above string.
-- As an example, consider:
@@ -1375,9 +1377,7 @@ package Exp_Dbug is
-- be encoded, as in ordinary C unions, as a single field of the
-- enclosing union type named "x" of type "T", dispensing with the
-- enclosing struct. In this case, of course, the discriminant values
- -- corresponding to the variant are unavailable. As for normal
- -- variants, the field name "x" may be suffixed with ___XVL if it
- -- has dynamic size.
+ -- corresponding to the variant are unavailable.
-- For example, the type Var in the preceding section, if followed by
-- "pragma Unchecked_Union (Var);" may be encoded as a struct with two
@@ -1549,46 +1549,19 @@ package Exp_Dbug is
-- are missing and deal as best as it can with the limited information
-- available.
- ---------------------------------
- -- GNAT Extensions to DWARF2/3 --
- ---------------------------------
-
- -- If the compiler switch "-gdwarf+" is specified, GNAT Vendor extensions
- -- to DWARF2/3 are generated, with the following variations from the above
- -- specification.
-
- -- Change in the contents of the DW_AT_name attribute
-
- -- The operators are represented in their natural form. (for example,
- -- the addition operator is written as "+" instead of "Oadd"). The
- -- component separator is "." instead of "__"
+ -----------------------------------------
+ -- GNAT Extensions to DWARF (OBSOLETE) --
+ -----------------------------------------
- -- Introduction of DW_AT_GNAT_encoding, encoded with value 0x2301
+ -- DW_AT_use_GNAT_descriptive_type, encoded with value 0x2301
- -- Any debugging information entry representing a program entity, named
- -- or implicit, may have a DW_AT_GNAT_encoding attribute. The value of
- -- this attribute is a string representing the suffix internally added
- -- by GNAT for various purposes, mainly for representing debug
- -- information compatible with other formats. In particular this is
- -- useful for IDEs which need to filter out information internal to
- -- GNAT from their graphical interfaces.
+ -- This extension has never been implemented in the compiler.
- -- If a debugging information entry has multiple encodings, all of them
- -- will be listed in DW_AT_GNAT_encoding using the list separator ':'.
-
- -- Introduction of DW_AT_GNAT_descriptive_type, encoded with value 0x2302
+ -- DW_AT_GNAT_descriptive_type, encoded with value 0x2302
-- Any debugging information entry representing a type may have a
-- DW_AT_GNAT_descriptive_type attribute whose value is a reference,
-- pointing to a debugging information entry representing another type
-- associated to the type.
- -- Modification of the contents of the DW_AT_producer string
-
- -- When emitting full GNAT Vendor extensions to DWARF2/3, "-gdwarf+"
- -- is appended to the DW_AT_producer string.
- --
- -- When emitting only DW_AT_GNAT_descriptive_type, "-gdwarf+-" is
- -- appended to the DW_AT_producer string.
-
end Exp_Dbug;
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index a2ea7c6..e9d6e74 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -588,19 +588,7 @@ package body Exp_Disp is
-- Otherwise, count the primitives of the enclosing CPP type
else
- declare
- Count : Nat := 0;
- Elmt : Elmt_Id;
-
- begin
- Elmt := First_Elmt (Primitive_Operations (CPP_Typ));
- while Present (Elmt) loop
- Count := Count + 1;
- Next_Elmt (Elmt);
- end loop;
-
- return Count;
- end;
+ return List_Length (Primitive_Operations (CPP_Typ));
end if;
end if;
end CPP_Num_Prims;
@@ -2575,11 +2563,9 @@ package body Exp_Disp is
New_List (
Obj_Ref,
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protected_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Protected_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
New_Occurrence_Of -- Asynchronous_Call
@@ -2598,11 +2584,9 @@ package body Exp_Disp is
Make_Assignment_Statement (Loc,
Name => Make_Identifier (Loc, Name_uB),
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Dummy_Communication_Block), Loc),
- Expression => New_Occurrence_Of (Com_Block, Loc))));
+ Unchecked_Convert_To
+ (RTE (RE_Dummy_Communication_Block),
+ New_Occurrence_Of (Com_Block, Loc))));
-- Generate:
-- F := False;
@@ -2636,10 +2620,9 @@ package body Exp_Disp is
Prefix => Make_Identifier (Loc, Name_uT),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Task_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
New_Occurrence_Of -- Asynchronous_Call
@@ -2929,11 +2912,9 @@ package body Exp_Disp is
Parameter_Associations => New_List (
Obj_Ref,
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protected_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Protected_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
@@ -3006,10 +2987,9 @@ package body Exp_Disp is
Prefix => Make_Identifier (Loc, Name_uT),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Task_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
New_Occurrence_Of -- Conditional_Call
@@ -3219,12 +3199,11 @@ package body Exp_Disp is
Ret :=
Make_Simple_Return_Statement (Loc,
Expression =>
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (RTE (RE_Address), Loc),
- Expression =>
- Make_Selected_Component (Loc,
- Prefix => Make_Identifier (Loc, Name_uT),
- Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));
+ Unchecked_Convert_To
+ (RTE (RE_Address),
+ Make_Selected_Component (Loc,
+ Prefix => Make_Identifier (Loc, Name_uT),
+ Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));
-- A null body is constructed for non-task types
@@ -3337,12 +3316,9 @@ package body Exp_Disp is
Parameter_Associations =>
New_List (
- Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
- Subtype_Mark =>
- New_Occurrence_Of (
- RTE (RE_Protection_Entries_Access), Loc),
- Expression =>
- Make_Identifier (Loc, Name_uP)),
+ Unchecked_Convert_To ( -- PEA (P)
+ RTE (RE_Protection_Entries_Access),
+ Make_Identifier (Loc, Name_uP)),
Make_Attribute_Reference (Loc, -- O._object'Acc
Attribute_Name =>
@@ -3354,11 +3330,9 @@ package body Exp_Disp is
Selector_Name =>
Make_Identifier (Loc, Name_uObject))),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protected_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Protected_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uA)))), -- abort status
@@ -3383,11 +3357,9 @@ package body Exp_Disp is
Selector_Name =>
Make_Identifier (Loc, Name_uObject))),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protected_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Protected_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uA)))))); -- abort status
end if;
@@ -3424,20 +3396,17 @@ package body Exp_Disp is
Parameter_Associations => New_List (
- Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protection_Entries_Access), Loc),
- Expression => Make_Identifier (Loc, Name_uP)),
+ Unchecked_Convert_To ( -- PEA (P)
+ RTE (RE_Protection_Entries_Access),
+ Make_Identifier (Loc, Name_uP)),
Make_Selected_Component (Loc, -- O._task_id
Prefix => Make_Identifier (Loc, Name_uO),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Task_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uA)))), -- abort status
@@ -3455,10 +3424,9 @@ package body Exp_Disp is
Prefix => Make_Identifier (Loc, Name_uO),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Task_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uA)))))); -- abort status
end if;
@@ -3743,11 +3711,9 @@ package body Exp_Disp is
Parameter_Associations => New_List (
Obj_Ref,
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of
- (RTE (RE_Protected_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Protected_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
Make_Identifier (Loc, Name_uD), -- delay
@@ -3786,10 +3752,9 @@ package body Exp_Disp is
Prefix => Make_Identifier (Loc, Name_uT),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
- Make_Unchecked_Type_Conversion (Loc, -- entry index
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
- Expression => Make_Identifier (Loc, Name_uI)),
+ Unchecked_Convert_To ( -- entry index
+ RTE (RE_Task_Entry_Index),
+ Make_Identifier (Loc, Name_uI)),
Make_Identifier (Loc, Name_uP), -- parameter block
Make_Identifier (Loc, Name_uD), -- delay
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb
index 9805457..5cb8fb5 100644
--- a/gcc/ada/exp_dist.adb
+++ b/gcc/ada/exp_dist.adb
@@ -1424,6 +1424,7 @@ package body Exp_Dist is
and then Chars (Current_Primitive) /= Name_uAlignment
and then not
(Is_TSS (Current_Primitive, TSS_Deep_Finalize) or else
+ Is_TSS (Current_Primitive, TSS_Put_Image) or else
Is_TSS (Current_Primitive, TSS_Stream_Input) or else
Is_TSS (Current_Primitive, TSS_Stream_Output) or else
Is_TSS (Current_Primitive, TSS_Stream_Read) or else
diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index 6e17a5c..d2605fb 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -37,6 +37,8 @@ with Namet; use Namet;
with Nmake; use Nmake;
with Nlists; use Nlists;
with Opt; use Opt;
+with Restrict; use Restrict;
+with Rident; use Rident;
with Rtsfind; use Rtsfind;
with Sem_Aux; use Sem_Aux;
with Sem_Res; use Sem_Res;
@@ -160,6 +162,8 @@ package body Exp_Imgv is
Expression => Make_Aggregate (Loc, Expressions => V)));
end Append_Table_To;
+ -- Start of Build_Enumeration_Image_Tables
+
begin
-- Nothing to do for types other than a root enumeration type
@@ -247,7 +251,7 @@ package body Exp_Imgv is
Append_Table_To (Act, Eind, Nlit, Ityp, Ind);
-- If the number of literals is not greater than Threshold, then we are
- -- done. Otherwise we compute a (perfect) hash function for use by the
+ -- done. Otherwise we generate a (perfect) hash function for use by the
-- Value attribute.
if Nlit > Threshold then
@@ -283,11 +287,12 @@ package body Exp_Imgv is
-- If the unit where the type is declared is the main unit, and the
-- number of literals is greater than Threshold_For_Size when we are
- -- optimizing for size, and -gnatd_h is not specified, try to compute
- -- the hash function.
+ -- optimizing for size, and the restriction No_Implicit_Loops is not
+ -- active, and -gnatd_h is not specified, generate the hash function.
if In_Main_Unit
and then (Optimize_Size = 0 or else Nlit > Threshold_For_Size)
+ and then not Restriction_Active (No_Implicit_Loops)
and then not Debug_Flag_Underscore_H
then
declare
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index 7e29502..47919fc 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -563,11 +563,11 @@ package body Exp_Pakd is
-- Do not reset RM_Size if already set, as happens in the case of
-- a modular type.
- if Unknown_Esize (PAT) then
+ if not Known_Esize (PAT) then
Set_Esize (PAT, PASize);
end if;
- if Unknown_RM_Size (PAT) then
+ if not Known_RM_Size (PAT) then
Set_RM_Size (PAT, PASize);
end if;
@@ -828,8 +828,8 @@ package body Exp_Pakd is
elsif not Is_Constrained (Typ) then
- -- When generating standard DWARF (i.e when GNAT_Encodings is
- -- DWARF_GNAT_Encodings_Minimal), the ___XP suffix will be stripped
+ -- When generating standard DWARF (i.e when GNAT_Encodings is not
+ -- DWARF_GNAT_Encodings_All), the ___XP suffix will be stripped
-- by the back-end but generate it anyway to ease compiler debugging.
-- This will help to distinguish implementation types from original
-- packed arrays.
diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
index 2828f5a..43ecdcd 100644
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -2361,6 +2361,7 @@ package body Exp_Prag is
S : Entity_Id;
E : Entity_Id;
+ Remove_Inspection_Point : Boolean := False;
begin
if No (Pragma_Argument_Associations (N)) then
A := New_List;
@@ -2400,6 +2401,36 @@ package body Exp_Prag is
Expand (Expression (Assoc));
Next (Assoc);
end loop;
+
+ -- If any of the references have a freeze node, it must appear before
+ -- pragma Inspection_Point, otherwise the entity won't be available when
+ -- Gigi processes Inspection_Point.
+ -- When this requirement isn't met, turn the pragma into a no-op.
+
+ Assoc := First (Pragma_Argument_Associations (N));
+ while Present (Assoc) loop
+
+ if Present (Freeze_Node (Entity (Expression (Assoc)))) and then
+ not Is_Frozen (Entity (Expression (Assoc)))
+ then
+ Error_Msg_NE ("??inspection point references unfrozen object &",
+ Assoc,
+ Entity (Expression (Assoc)));
+ Remove_Inspection_Point := True;
+ end if;
+
+ Next (Assoc);
+ end loop;
+
+ if Remove_Inspection_Point then
+ Error_Msg_N ("\pragma will be ignored", N);
+
+ -- We can't just remove the pragma from the tree as it might be
+ -- iterated over by the caller. Turn it into a null statement
+ -- instead.
+
+ Rewrite (N, Make_Null_Statement (Sloc (N)));
+ end if;
end Expand_Pragma_Inspection_Point;
--------------------------------------
diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb
index 33c72c3..90a542d 100644
--- a/gcc/ada/exp_put_image.adb
+++ b/gcc/ada/exp_put_image.adb
@@ -23,13 +23,14 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
+with Csets; use Csets;
with Einfo; use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils; use Einfo.Utils;
with Exp_Tss; use Exp_Tss;
-with Exp_Util;
-with Debug; use Debug;
+with Exp_Util; use Exp_Util;
with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
@@ -43,15 +44,13 @@ with Sinfo.Nodes; use Sinfo.Nodes;
with Sinfo.Utils; use Sinfo.Utils;
with Snames; use Snames;
with Stand;
+with Stringt; use Stringt;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
package body Exp_Put_Image is
- Tagged_Put_Image_Enabled : Boolean renames Debug_Flag_Underscore_Z;
- -- ???Set True to enable Put_Image for at least some tagged types
-
-----------------------
-- Local Subprograms --
-----------------------
@@ -529,6 +528,7 @@ package body Exp_Put_Image is
Pnam : out Entity_Id)
is
Btyp : constant Entity_Id := Base_Type (Typ);
+ pragma Assert (not Is_Class_Wide_Type (Btyp));
pragma Assert (not Is_Unchecked_Union (Btyp));
First_Time : Boolean := True;
@@ -649,32 +649,90 @@ package body Exp_Put_Image is
-- Loop through components, skipping all internal components,
-- which are not part of the value (e.g. _Tag), except that we
-- don't skip the _Parent, since we do want to process that
- -- recursively. If _Parent is an interface type, being abstract
- -- with no components there is no need to handle it.
+ -- recursively.
while Present (Item) loop
if Nkind (Item) in
N_Component_Declaration | N_Discriminant_Specification
- and then
- ((Chars (Defining_Identifier (Item)) = Name_uParent
- and then not Is_Interface
- (Etype (Defining_Identifier (Item))))
- or else
- not Is_Internal_Name (Chars (Defining_Identifier (Item))))
then
- if First_Time then
- First_Time := False;
- else
- Append_To (Result,
- Make_Procedure_Call_Statement (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Record_Between), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ if Chars (Defining_Identifier (Item)) = Name_uParent then
+ declare
+ Parent_Type : constant Entity_Id :=
+ Implementation_Base_Type
+ (Etype (Defining_Identifier (Item)));
+
+ Parent_Aspect_Spec : constant Node_Id :=
+ Find_Aspect (Parent_Type, Aspect_Put_Image);
+
+ Parent_Type_Decl : constant Node_Id :=
+ Declaration_Node (Parent_Type);
+
+ Parent_Rdef : Node_Id :=
+ Type_Definition (Parent_Type_Decl);
+ begin
+ -- If parent type has an noninherited
+ -- explicitly-specified Put_Image aspect spec, then
+ -- display parent part by calling specified procedure,
+ -- and then use extension-aggregate syntax for the
+ -- remaining components as per RM 4.10(15/5);
+ -- otherwise, "look through" the parent component
+ -- to its components - we don't want the image text
+ -- to include mention of an "_parent" component.
+
+ if Present (Parent_Aspect_Spec) and then
+ Entity (Parent_Aspect_Spec) = Parent_Type
+ then
+ Append_Component_Attr
+ (Result, Defining_Identifier (Item));
+
+ -- Omit the " with " if no subsequent components.
+
+ if not Is_Null_Extension_Of
+ (Descendant => Typ,
+ Ancestor => Parent_Type)
+ then
+ Append_To (Result,
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of
+ (RTE (RE_Put_UTF_8), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S),
+ Make_String_Literal (Loc, " with "))));
+ end if;
+ else
+ if Nkind (Parent_Rdef) = N_Derived_Type_Definition
+ then
+ Parent_Rdef :=
+ Record_Extension_Part (Parent_Rdef);
+ end if;
+
+ if Present (Component_List (Parent_Rdef)) then
+ Append_List_To (Result,
+ Make_Component_List_Attributes
+ (Component_List (Parent_Rdef)));
+ end if;
+ end if;
+ end;
+
+ elsif not Is_Internal_Name
+ (Chars (Defining_Identifier (Item)))
+ then
+ if First_Time then
+ First_Time := False;
+ else
+ Append_To (Result,
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Record_Between), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
+ end if;
+
+ Append_To (Result, Make_Component_Name (Item));
+ Append_Component_Attr
+ (Result, Defining_Identifier (Item));
end if;
-
- Append_To (Result, Make_Component_Name (Item));
- Append_Component_Attr (Result, Defining_Identifier (Item));
end if;
Next (Item);
@@ -690,13 +748,35 @@ package body Exp_Put_Image is
function Make_Component_Name (C : Entity_Id) return Node_Id is
Name : constant Name_Id := Chars (Defining_Identifier (C));
+ pragma Assert (Name /= Name_uParent);
+
+ function To_Upper (S : String) return String;
+ -- Same as Ada.Characters.Handling.To_Upper, but withing
+ -- Ada.Characters.Handling seems to cause mailserver problems.
+
+ --------------
+ -- To_Upper --
+ --------------
+
+ function To_Upper (S : String) return String is
+ begin
+ return Result : String := S do
+ for Char of Result loop
+ Char := Fold_Upper (Char);
+ end loop;
+ end return;
+ end To_Upper;
+
+ -- Start of processing for Make_Component_Name
+
begin
return
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
Parameter_Associations => New_List
(Make_Identifier (Loc, Name_S),
- Make_String_Literal (Loc, Get_Name_String (Name) & " => ")));
+ Make_String_Literal (Loc,
+ To_Upper (Get_Name_String (Name)) & " => ")));
end Make_Component_Name;
Stms : constant List_Id := New_List;
@@ -707,38 +787,71 @@ package body Exp_Put_Image is
-- Start of processing for Build_Record_Put_Image_Procedure
begin
- Append_To (Stms,
- Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Record_Before), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ if (Ada_Version < Ada_2022)
+ or else not Enable_Put_Image (Btyp)
+ then
+ -- generate a very simple Put_Image implementation
- -- Generate Put_Images for the discriminants of the type
+ if Is_RTE (Typ, RE_Root_Buffer_Type) then
+ -- Avoid introducing a cyclic dependency between
+ -- Ada.Strings.Text_Buffers and System.Put_Images.
- Append_List_To (Stms,
- Make_Component_Attributes (Discriminant_Specifications (Type_Decl)));
+ Append_To (Stms,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Explicit_Raise));
+ else
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Put_Image_Unknown), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S),
+ Make_String_Literal (Loc,
+ To_String (Fully_Qualified_Name_String (Btyp))))));
+ end if;
+ elsif Is_Null_Record_Type (Btyp, Ignore_Privacy => True) then
- Rdef := Type_Definition (Type_Decl);
+ -- Interface types take this path.
- -- In the record extension case, the components we want, including the
- -- _Parent component representing the parent type, are to be found in
- -- the extension. We will process the _Parent component using the type
- -- of the parent.
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S),
+ Make_String_Literal (Loc, "(NULL RECORD)"))));
+ else
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Record_Before), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
- if Nkind (Rdef) = N_Derived_Type_Definition then
- Rdef := Record_Extension_Part (Rdef);
- end if;
+ -- Generate Put_Images for the discriminants of the type
- if Present (Component_List (Rdef)) then
Append_List_To (Stms,
- Make_Component_List_Attributes (Component_List (Rdef)));
- end if;
+ Make_Component_Attributes
+ (Discriminant_Specifications (Type_Decl)));
- Append_To (Stms,
- Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Record_After), Loc),
- Parameter_Associations => New_List
- (Make_Identifier (Loc, Name_S))));
+ Rdef := Type_Definition (Type_Decl);
+
+ -- In the record extension case, the components we want are to be
+ -- found in the extension (although we have to process the
+ -- _Parent component to find inherited components).
+
+ if Nkind (Rdef) = N_Derived_Type_Definition then
+ Rdef := Record_Extension_Part (Rdef);
+ end if;
+
+ if Present (Component_List (Rdef)) then
+ Append_List_To (Stms,
+ Make_Component_List_Attributes (Component_List (Rdef)));
+ end if;
+
+ Append_To (Stms,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_Record_After), Loc),
+ Parameter_Associations => New_List
+ (Make_Identifier (Loc, Name_S))));
+ end if;
Pnam := Make_Put_Image_Name (Loc, Btyp);
Build_Put_Image_Proc (Loc, Btyp, Decl, Pnam, Stms);
@@ -817,41 +930,29 @@ package body Exp_Put_Image is
function Enable_Put_Image (Typ : Entity_Id) return Boolean is
begin
+ -- If this function returns False for a non-scalar type Typ, then
+ -- a) calls to Typ'Image will result in calls to
+ -- System.Put_Images.Put_Image_Unknown to generate the image.
+ -- b) If Typ is a tagged type, then similarly the implementation
+ -- of Typ's Put_Image procedure will call Put_Image_Unknown
+ -- and will ignore its formal parameter of type Typ.
+ -- Note that Typ will still have a Put_Image procedure
+ -- in this case, albeit one with a simplified implementation.
+ --
-- The name "Sink" here is a short nickname for
-- "Ada.Strings.Text_Buffers.Root_Buffer_Type".
-
- -- There's a bit of a chicken&egg problem. The compiler is likely to
- -- have trouble if we refer to the Put_Image of Sink itself, because
- -- Sink is part of the parameter profile:
- --
- -- function Sink'Put_Image (S : in out Sink'Class; V : T);
- --
- -- Likewise, the Ada.Strings.Buffer package, where Sink is
- -- declared, depends on various other packages, so if we refer to
- -- Put_Image of types declared in those other packages, we could create
- -- cyclic dependencies. Therefore, we disable Put_Image for some
- -- types. It's not clear exactly what types should be disabled. Scalar
- -- types are OK, even if predefined, because calls to Put_Image of
- -- scalar types are expanded inline. We certainly want to be able to use
- -- Integer'Put_Image, for example.
-
- -- ???Temporarily disable to work around bugs:
--
-- Put_Image does not work for Remote_Types. We check the containing
-- package, rather than the type itself, because we want to include
-- types in the private part of a Remote_Types package.
- --
- -- Put_Image on tagged types triggers some bugs.
if Is_Remote_Types (Scope (Typ))
+ or else Is_Remote_Call_Interface (Typ)
or else (Is_Tagged_Type (Typ) and then In_Predefined_Unit (Typ))
- or else (Is_Tagged_Type (Typ) and then not Tagged_Put_Image_Enabled)
then
return False;
end if;
- -- End of workarounds.
-
-- No sense in generating code for Put_Image if there are errors. This
-- avoids certain cascade errors.
@@ -904,9 +1005,9 @@ package body Exp_Put_Image is
return True;
end Enable_Put_Image;
- ---------------------------------
+ -------------------------
-- Make_Put_Image_Name --
- ---------------------------------
+ -------------------------
function Make_Put_Image_Name
(Loc : Source_Ptr; Typ : Entity_Id) return Entity_Id
@@ -927,6 +1028,10 @@ package body Exp_Put_Image is
return Make_Defining_Identifier (Loc, Sname);
end Make_Put_Image_Name;
+ ---------------------------------
+ -- Image_Should_Call_Put_Image --
+ ---------------------------------
+
function Image_Should_Call_Put_Image (N : Node_Id) return Boolean is
begin
if Ada_Version < Ada_2022 then
@@ -948,11 +1053,15 @@ package body Exp_Put_Image is
end;
end Image_Should_Call_Put_Image;
+ ----------------------
+ -- Build_Image_Call --
+ ----------------------
+
function Build_Image_Call (N : Node_Id) return Node_Id is
-- For T'Image (X) Generate an Expression_With_Actions node:
--
-- do
- -- S : Buffer := New_Buffer;
+ -- S : Buffer;
-- U_Type'Put_Image (S, X);
-- Result : constant String := Get (S);
-- Destroy (S);
@@ -970,13 +1079,16 @@ package body Exp_Put_Image is
Object_Definition =>
New_Occurrence_Of (RTE (RE_Buffer_Type), Loc));
+ Image_Prefix : constant Node_Id :=
+ Duplicate_Subexpr (First (Expressions (N)));
+
Put_Im : constant Node_Id :=
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (U_Type, Loc),
Attribute_Name => Name_Put_Image,
Expressions => New_List (
New_Occurrence_Of (Sink_Entity, Loc),
- New_Copy_Tree (First (Expressions (N)))));
+ Image_Prefix));
Result_Entity : constant Entity_Id :=
Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('R'));
Result_Decl : constant Node_Id :=
@@ -989,12 +1101,86 @@ package body Exp_Put_Image is
Name => New_Occurrence_Of (RTE (RE_Get), Loc),
Parameter_Associations => New_List (
New_Occurrence_Of (Sink_Entity, Loc))));
- Image : constant Node_Id :=
- Make_Expression_With_Actions (Loc,
- Actions => New_List (Sink_Decl, Put_Im, Result_Decl),
- Expression => New_Occurrence_Of (Result_Entity, Loc));
+ Actions : List_Id;
+
+ function Put_String_Exp (String_Exp : Node_Id;
+ Wide_Wide : Boolean := False) return Node_Id;
+ -- Generate a call to evaluate a String (or Wide_Wide_String, depending
+ -- on the Wide_Wide Boolean parameter) expression and output it into
+ -- the buffer.
+
+ --------------------
+ -- Put_String_Exp --
+ --------------------
+
+ function Put_String_Exp (String_Exp : Node_Id;
+ Wide_Wide : Boolean := False) return Node_Id is
+ Put_Id : constant RE_Id :=
+ (if Wide_Wide then RE_Wide_Wide_Put else RE_Put_UTF_8);
+
+ -- We could build a nondispatching call here, but to make
+ -- that work we'd have to change Rtsfind spec to make available
+ -- corresponding callees out of Ada.Strings.Text_Buffers.Unbounded
+ -- (as opposed to from Ada.Strings.Text_Buffers). Seems simpler to
+ -- introduce a type conversion and leave it to the optimizer to
+ -- eliminate the dispatching. This does not *introduce* any problems
+ -- if a no-dispatching-allowed restriction is in effect, since we
+ -- are already in the middle of generating a call to T'Class'Image.
+
+ Sink_Exp : constant Node_Id :=
+ Make_Type_Conversion (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of
+ (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc),
+ Expression => New_Occurrence_Of (Sink_Entity, Loc));
+ begin
+ return
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (Put_Id), Loc),
+ Parameter_Associations => New_List (Sink_Exp, String_Exp));
+ end Put_String_Exp;
+
+ -- Start of processing for Build_Image_Call
+
begin
- return Image;
+ if Is_Class_Wide_Type (U_Type) then
+ -- Generate qualified-expression syntax; qualification name comes
+ -- from calling Ada.Tags.Wide_Wide_Expanded_Name.
+
+ declare
+ -- The copy of Image_Prefix will be evaluated before the
+ -- original, which is ok if no side effects are involved.
+
+ pragma Assert (Side_Effect_Free (Image_Prefix));
+
+ Specific_Type_Name : constant Node_Id :=
+ Put_String_Exp
+ (Make_Function_Call (Loc,
+ Name => New_Occurrence_Of
+ (RTE (RE_Wide_Wide_Expanded_Name), Loc),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => Duplicate_Subexpr (Image_Prefix),
+ Attribute_Name => Name_Tag))),
+ Wide_Wide => True);
+
+ Qualification : constant Node_Id :=
+ Put_String_Exp (Make_String_Literal (Loc, "'"));
+ begin
+ Actions := New_List
+ (Sink_Decl,
+ Specific_Type_Name,
+ Qualification,
+ Put_Im,
+ Result_Decl);
+ end;
+ else
+ Actions := New_List (Sink_Decl, Put_Im, Result_Decl);
+ end if;
+
+ return Make_Expression_With_Actions (Loc,
+ Actions => Actions,
+ Expression => New_Occurrence_Of (Result_Entity, Loc));
end Build_Image_Call;
------------------------------
@@ -1023,7 +1209,6 @@ package body Exp_Put_Image is
-- Don't do it if type Root_Buffer_Type is unavailable in the runtime.
if not In_Predefined_Unit (Compilation_Unit)
- and then Tagged_Put_Image_Enabled
and then Tagged_Seen
and then not No_Run_Time_Mode
and then RTE_Available (RE_Root_Buffer_Type)
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 270242d..2584041 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1467,9 +1467,7 @@ package body Exp_Util is
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 => Obj_Name)));
+ Unchecked_Convert_To (Formal_Typ, Obj_Name)));
end Build_DIC_Call;
------------------------------
@@ -9050,7 +9048,7 @@ package body Exp_Util is
if Target_Strict_Alignment
and then Known_Alignment (Ptyp)
- and then (Unknown_Alignment (Styp)
+ and then (not Known_Alignment (Styp)
or else Alignment (Styp) > Alignment (Ptyp))
then
return True;
@@ -9074,7 +9072,7 @@ package body Exp_Util is
begin
if Present (Component_Clause (Field))
and then
- (Unknown_Alignment (Styp)
+ (not Known_Alignment (Styp)
or else
(Component_Bit_Offset (Field) mod
(System_Storage_Unit * Alignment (Styp))) /= 0)
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 2b3147d..5c931c9 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -162,7 +162,7 @@ package Exp_Util is
--
-- Implementation limitation: Assoc_Node must be a statement. We can
-- generalize to expressions if there is a need but this is tricky to
- -- implement because of short-circuits (among other things).???
+ -- implement because of short-circuits (among other things).
procedure Insert_Declaration (N : Node_Id; Decl : Node_Id);
-- N must be a subexpression (Nkind in N_Subexpr). This is similar to
@@ -915,7 +915,7 @@ package Exp_Util is
-- Establish the following mapping between the attributes of tagged parent
-- type Parent_Type and tagged derived type Derived_Type.
--
- -- * Map each discriminant of Parent_Type to ether the corresponding
+ -- * Map each discriminant of Parent_Type to either the corresponding
-- discriminant of Derived_Type or come constraint.
-- * Map each primitive operation of Parent_Type to the corresponding
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 3e42f16..d7ab361b 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -636,30 +636,6 @@ B Known_Static_Normalized_Position_Max (Entity_Id E);
#define Known_Static_RM_Size einfo__utils__known_static_rm_size
B Known_Static_RM_Size (Entity_Id E);
-#define Unknown_Alignment einfo__utils__unknown_alignment
-B Unknown_Alignment (Entity_Id E);
-
-#define Unknown_Component_Bit_Offset einfo__utils__unknown_component_bit_offset
-B Unknown_Component_Bit_Offset (Entity_Id E);
-
-#define Unknown_Component_Size einfo__utils__unknown_component_size
-B Unknown_Component_Size (Entity_Id E);
-
-#define Unknown_Esize einfo__utils__unknown_esize
-B Unknown_Esize (Entity_Id E);
-
-#define Unknown_Normalized_First_Bit einfo__utils__unknown_normalized_first_bit
-B Unknown_Normalized_First_Bit (Entity_Id E);
-
-#define Unknown_Normalized_Position einfo__utils__unknown_normalized_position
-B Unknown_Normalized_Position (Entity_Id E);
-
-#define Unknown_Normalized_Position_Max einfo__utils__unknown_normalized_position_max
-B Unknown_Normalized_Position_Max (Entity_Id E);
-
-#define Unknown_RM_Size einfo__utils__unknown_rm_size
-B Unknown_RM_Size (Entity_Id E);
-
#define Is_Discrete_Or_Fixed_Point_Type einfo__utils__is_discrete_or_fixed_point_type
B Is_Discrete_Or_Fixed_Point_Type (E Id);
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 81e0e87..12d10ee 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -857,7 +857,7 @@ package body Freeze is
-- Set size if not set already
- elsif Unknown_RM_Size (T) then
+ elsif not Known_RM_Size (T) then
Set_RM_Size (T, S);
end if;
end Set_Small_Size;
@@ -867,11 +867,8 @@ package body Freeze is
----------------
function Size_Known (T : Entity_Id) return Boolean is
- Index : Entity_Id;
Comp : Entity_Id;
Ctyp : Entity_Id;
- Low : Node_Id;
- High : Node_Id;
begin
if Size_Known_At_Compile_Time (T) then
@@ -918,8 +915,11 @@ package body Freeze is
-- thus may be packable).
declare
- Size : Uint := Component_Size (T);
- Dim : Uint;
+ Index : Entity_Id;
+ Low : Node_Id;
+ High : Node_Id;
+ Size : Uint := Component_Size (T);
+ Dim : Uint;
begin
Index := First_Index (T);
@@ -1043,7 +1043,7 @@ package body Freeze is
if not Is_Constrained (T)
and then
No (Discriminant_Default_Value (First_Discriminant (T)))
- and then Unknown_RM_Size (T)
+ and then not Known_RM_Size (T)
then
return False;
end if;
@@ -1671,6 +1671,12 @@ package body Freeze is
-- type declaration that generates inherited operation. For
-- a null procedure, the declaration implies a null body.
+ -- Before insertion, do some minimal decoration of fields
+
+ Mutate_Ekind (New_Id, Ekind (Par_Prim));
+ Set_LSP_Subprogram (New_Id, Par_Prim);
+ Set_Is_Wrapper (New_Id);
+
if Nkind (New_Spec) = N_Procedure_Specification
and then Null_Present (New_Spec)
then
@@ -1684,12 +1690,6 @@ package body Freeze is
Build_Class_Wide_Clone_Call
(Loc, Decls, Par_Prim, New_Spec);
- -- Adding minimum decoration
-
- Mutate_Ekind (New_Id, Ekind (Par_Prim));
- Set_LSP_Subprogram (New_Id, Par_Prim);
- Set_Is_Wrapper (New_Id);
-
Insert_List_After_And_Analyze
(Par_R, New_List (New_Decl, New_Body));
@@ -3480,7 +3480,7 @@ package body Freeze is
else
-- Acquire alignment from base type
- if Unknown_Alignment (Arr) then
+ if not Known_Alignment (Arr) then
Set_Alignment (Arr, Alignment (Base_Type (Arr)));
Adjust_Esize_Alignment (Arr);
end if;
@@ -4141,9 +4141,10 @@ package body Freeze is
elsif not After_Last_Declaration
and then not Freezing_Library_Level_Tagged_Type
then
- Error_Msg_Node_1 := F_Type;
- Error_Msg_N
- ("type & must be fully defined before this point", N);
+ Error_Msg_NE
+ ("type & must be fully defined before this point",
+ N,
+ F_Type);
end if;
end if;
@@ -7590,6 +7591,7 @@ package body Freeze is
or else Is_TSS (Id, TSS_Stream_Output)
or else Is_TSS (Id, TSS_Stream_Read)
or else Is_TSS (Id, TSS_Stream_Write)
+ or else Is_TSS (Id, TSS_Put_Image)
or else Nkind (Original_Node (P)) =
N_Subprogram_Renaming_Declaration)
then
@@ -8630,7 +8632,7 @@ package body Freeze is
-- If Esize of a subtype has not previously been set, set it now
- if Unknown_Esize (Typ) then
+ if not Known_Esize (Typ) then
Atype := Ancestor_Subtype (Typ);
if Present (Atype) then
@@ -9125,7 +9127,7 @@ package body Freeze is
-- Set Esize to calculated size if not set already
- if Unknown_Esize (Typ) then
+ if not Known_Esize (Typ) then
Init_Esize (Typ, Actual_Size);
end if;
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 6fc94dd..b09e20d 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -444,7 +444,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* The RM size must be specified for all discrete and fixed-point types. */
gcc_assert (!(Is_In_Discrete_Or_Fixed_Point_Kind (kind)
- && Unknown_RM_Size (gnat_entity)));
+ && !Known_RM_Size (gnat_entity)));
/* If we get here, it means we have not yet done anything with this entity.
If we are not defining it, it must be a type or an entity that is defined
@@ -2324,7 +2324,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* If Component_Size is not already specified, annotate it with the
size of the component. */
- if (Unknown_Component_Size (gnat_entity))
+ if (!Known_Component_Size (gnat_entity))
Set_Component_Size (gnat_entity,
annotate_value (TYPE_SIZE (comp_type)));
@@ -4369,7 +4369,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
set_rm_size (RM_Size (gnat_entity), gnu_type, gnat_entity);
/* Back-annotate the alignment of the type if not already set. */
- if (Unknown_Alignment (gnat_entity))
+ if (!Known_Alignment (gnat_entity))
{
unsigned int double_align, align;
bool is_capped_double, align_clause;
@@ -4395,7 +4395,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
}
/* Likewise for the size, if any. */
- if (Unknown_Esize (gnat_entity) && TYPE_SIZE (gnu_type))
+ if (!Known_Esize (gnat_entity) && TYPE_SIZE (gnu_type))
{
tree gnu_size = TYPE_SIZE (gnu_type);
@@ -4428,7 +4428,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* If there is neither size clause nor representation clause, the
sizes need to be adjusted. */
- if (Unknown_RM_Size (gnat_entity)
+ if (!Known_RM_Size (gnat_entity)
&& !VOID_TYPE_P (gnu_type)
&& (!TYPE_FIELDS (gnu_type)
|| integer_zerop (bit_position (TYPE_FIELDS (gnu_type)))))
@@ -4448,7 +4448,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
Set_Esize (gnat_entity, annotate_value (gnu_size));
/* Tagged types are Strict_Alignment so RM_Size = Esize. */
- if (Unknown_RM_Size (gnat_entity))
+ if (!Known_RM_Size (gnat_entity))
Set_RM_Size (gnat_entity, Esize (gnat_entity));
}
@@ -4458,7 +4458,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
}
/* Likewise for the RM size, if any. */
- if (Unknown_RM_Size (gnat_entity) && TYPE_SIZE (gnu_type))
+ if (!Known_RM_Size (gnat_entity) && TYPE_SIZE (gnu_type))
Set_RM_Size (gnat_entity, annotate_value (rm_size (gnu_type)));
/* If we are at global level, GCC applied variable_size to the size but
@@ -4723,11 +4723,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
&& !TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl))
&& Present (gnat_annotate_type))
{
- if (Unknown_Alignment (gnat_entity))
+ if (!Known_Alignment (gnat_entity))
Set_Alignment (gnat_entity, Alignment (gnat_annotate_type));
- if (Unknown_Esize (gnat_entity))
+ if (!Known_Esize (gnat_entity))
Set_Esize (gnat_entity, Esize (gnat_annotate_type));
- if (Unknown_RM_Size (gnat_entity))
+ if (!Known_RM_Size (gnat_entity))
Set_RM_Size (gnat_entity, RM_Size (gnat_annotate_type));
}
@@ -8686,7 +8686,7 @@ annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref)
gnu_type = TREE_TYPE (gnu_type);
}
- if (Unknown_Esize (gnat_entity))
+ if (!Known_Esize (gnat_entity))
{
if (TREE_CODE (gnu_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_type))
@@ -8698,7 +8698,7 @@ annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref)
Set_Esize (gnat_entity, annotate_value (size));
}
- if (Unknown_Alignment (gnat_entity))
+ if (!Known_Alignment (gnat_entity))
Set_Alignment (gnat_entity,
UI_From_Int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
}
diff --git a/gcc/ada/gcc-interface/system.ads b/gcc/ada/gcc-interface/system.ads
index a468ae7..cfd9bb9 100644
--- a/gcc/ada/gcc-interface/system.ads
+++ b/gcc/ada/gcc-interface/system.ads
@@ -50,6 +50,10 @@ pragma Restrictions (No_Finalization);
-- access type on incomplete type Perm_Tree_Wrapper (which is required for
-- defining a recursive type).
+pragma Restrictions (No_Tasking);
+-- Make it explicit that tasking is not used in the compiler, which also
+-- allows generating simpler and more efficient code.
+
package System is
pragma Pure;
-- Note that we take advantage of the implementation permission to make
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 6a7424f..8f8bc70 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -9273,13 +9273,13 @@ process_freeze_entity (Node_Id gnat_node)
gnu_new = gnat_to_gnu_entity (full_view, NULL_TREE, true);
/* Propagate back-annotations from full view to partial view. */
- if (Unknown_Alignment (gnat_entity))
+ if (!Known_Alignment (gnat_entity))
Set_Alignment (gnat_entity, Alignment (full_view));
- if (Unknown_Esize (gnat_entity))
+ if (!Known_Esize (gnat_entity))
Set_Esize (gnat_entity, Esize (full_view));
- if (Unknown_RM_Size (gnat_entity))
+ if (!Known_RM_Size (gnat_entity))
Set_RM_Size (gnat_entity, RM_Size (full_view));
/* The above call may have defined this entity (the simplest example
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 982274c..535f4ca 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3543,9 +3543,6 @@ finish_subprog_decl (tree decl, tree asm_name, tree type)
DECL_BY_REFERENCE (result_decl) = TREE_ADDRESSABLE (type);
DECL_RESULT (decl) = result_decl;
- /* Propagate the "const" property. */
- TREE_READONLY (decl) = TYPE_READONLY (type);
-
/* Propagate the "pure" property. */
DECL_PURE_P (decl) = TYPE_RESTRICT (type);
diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index 603f08a..e2592ee 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -150,14 +150,12 @@ package Gen_IL.Fields is
Discrete_Subtype_Definitions,
Discriminant_Specifications,
Discriminant_Type,
- Do_Accessibility_Check,
Do_Discriminant_Check,
Do_Division_Check,
Do_Length_Check,
Do_Overflow_Check,
Do_Range_Check,
Do_Storage_Check,
- Do_Tag_Check,
Elaborate_All_Desirable,
Elaborate_All_Present,
Elaborate_Desirable,
diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb
index f5040b2..d5977ad 100644
--- a/gcc/ada/gen_il-gen-gen_entities.adb
+++ b/gcc/ada/gen_il-gen-gen_entities.adb
@@ -238,7 +238,9 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Warnings_Off_Used_Unreferenced, Flag),
Sm (Was_Hidden, Flag)));
- Cc (E_Void, Entity_Kind,
+ Ab (Void_Or_Type_Kind, Entity_Kind);
+
+ Cc (E_Void, Void_Or_Type_Kind,
-- The initial Ekind value for a newly created entity. Also used as the
-- Ekind for Standard_Void_Type, a type entity in Standard used as a
-- dummy type for the return type of a procedure (the reason we create
@@ -300,7 +302,9 @@ begin -- Gen_IL.Gen.Gen_Entities
-- but not getters; the Ekind is modified before any such getters are
-- called.
- Ab (Object_Kind, Entity_Kind,
+ Ab (Exception_Or_Object_Kind, Entity_Kind);
+
+ Ab (Object_Kind, Exception_Or_Object_Kind,
(Sm (Current_Value, Node_Id),
Sm (Renamed_Or_Alias, Node_Id)));
@@ -311,15 +315,14 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Entry_Formal, Node_Id),
Sm (Esize, Uint),
Sm (Interface_Name, Node_Id),
- Sm (Linker_Section_Pragma, Node_Id),
Sm (Normalized_First_Bit, Uint),
Sm (Normalized_Position, Uint),
Sm (Normalized_Position_Max, Uint),
Sm (Original_Record_Component, Node_Id)));
Cc (E_Component, Record_Field_Kind,
- -- Components of a record declaration, private declarations of
- -- protected objects.
+ -- Components (other than discriminants) of a record declaration,
+ -- private declarations of protected objects.
(Sm (Discriminant_Checking_Func, Node_Id),
Sm (DT_Entry_Count, Uint,
Pre => "Is_Tag (N)"),
@@ -452,7 +455,7 @@ begin -- Gen_IL.Gen.Gen_Entities
Cc (E_Named_Real, Named_Kind);
-- Named numbers created by a number declaration with a real value
- Ab (Type_Kind, Entity_Kind,
+ Ab (Type_Kind, Void_Or_Type_Kind,
(Sm (Alignment, Uint),
Sm (Associated_Node_For_Itype, Node_Id),
Sm (Can_Use_Internal_Rep, Flag, Base_Type_Only,
@@ -461,6 +464,7 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Contract, Node_Id),
Sm (Current_Use_Clause, Node_Id),
Sm (Derived_Type_Link, Node_Id),
+ Sm (Direct_Primitive_Operations, Elist_Id),
Sm (Predicates_Ignored, Flag),
Sm (Esize, Uint),
Sm (Finalize_Storage_Only, Flag, Base_Type_Only),
@@ -560,11 +564,9 @@ begin -- Gen_IL.Gen.Gen_Entities
Ab (Signed_Integer_Kind, Integer_Kind,
(Sm (First_Entity, Node_Id)));
- Cc (E_Signed_Integer_Type, Signed_Integer_Kind,
+ Cc (E_Signed_Integer_Type, Signed_Integer_Kind);
-- Signed integer type, used for the anonymous base type of the
-- integer subtype created by an integer type declaration.
- (Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)")));
Cc (E_Signed_Integer_Subtype, Signed_Integer_Kind);
-- Signed integer subtype, created by either an integer subtype or
@@ -648,14 +650,12 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (No_Strict_Aliasing, Flag, Base_Type_Only),
Sm (Storage_Size_Variable, Node_Id, Impl_Base_Type_Only)));
- Cc (E_Access_Type, Access_Kind,
+ Cc (E_Access_Type, Access_Kind);
-- An access type created by an access type declaration with no all
-- keyword present. Note that the predefined type Any_Access, which
-- has E_Access_Type Ekind, is used to label NULL in the upwards pass
-- of type analysis, to be replaced by the true access type in the
-- downwards resolution pass.
- (Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)")));
Cc (E_Access_Subtype, Access_Kind);
-- An access subtype created by a subtype declaration for any access
@@ -739,8 +739,6 @@ begin -- Gen_IL.Gen.Gen_Entities
-- An array subtype, created by an explicit array subtype declaration,
-- or the use of an anonymous array subtype.
(Sm (Predicated_Parent, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (First_Entity, Node_Id),
Sm (Static_Real_Or_String_Predicate, Node_Id)));
@@ -752,8 +750,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Ab (Class_Wide_Kind, Aggregate_Kind,
(Sm (C_Pass_By_Copy, Flag, Impl_Base_Type_Only),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (Equivalent_Type, Node_Id),
Sm (First_Entity, Node_Id),
Sm (Has_Complex_Representation, Flag, Impl_Base_Type_Only),
@@ -785,8 +781,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (C_Pass_By_Copy, Flag, Impl_Base_Type_Only),
Sm (Corresponding_Concurrent_Type, Node_Id),
Sm (Corresponding_Remote_Type, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (Dispatch_Table_Wrappers, Elist_Id, Impl_Base_Type_Only),
Sm (First_Entity, Node_Id),
Sm (Has_Complex_Representation, Flag, Impl_Base_Type_Only),
@@ -807,8 +801,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Cloned_Subtype, Node_Id),
Sm (Corresponding_Remote_Type, Node_Id),
Sm (Predicated_Parent, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (Dispatch_Table_Wrappers, Elist_Id, Impl_Base_Type_Only),
Sm (First_Entity, Node_Id),
Sm (Has_Complex_Representation, Flag, Impl_Base_Type_Only),
@@ -841,8 +833,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (C_Pass_By_Copy, Flag, Impl_Base_Type_Only),
Sm (Component_Alignment, Component_Alignment_Kind, Base_Type_Only),
Sm (Corresponding_Remote_Type, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (Has_Complex_Representation, Flag, Impl_Base_Type_Only),
Sm (Has_Pragma_Pack, Flag, Impl_Base_Type_Only),
Sm (Has_Record_Rep_Clause, Flag, Impl_Base_Type_Only),
@@ -861,8 +851,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Sm (Component_Alignment, Component_Alignment_Kind, Base_Type_Only),
Sm (Corresponding_Remote_Type, Node_Id),
Sm (Predicated_Parent, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (Has_Complex_Representation, Flag, Impl_Base_Type_Only),
Sm (Has_Pragma_Pack, Flag, Impl_Base_Type_Only),
Sm (Has_Record_Rep_Clause, Flag, Impl_Base_Type_Only),
@@ -877,17 +865,13 @@ begin -- Gen_IL.Gen.Gen_Entities
Cc (E_Private_Type, Private_Kind,
-- A private type, created by a private type declaration that has
-- neither the keyword limited nor the keyword tagged.
- (Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
- Sm (Scalar_Range, Node_Id),
+ (Sm (Scalar_Range, Node_Id),
Sm (Scope_Depth_Value, Uint)));
Cc (E_Private_Subtype, Private_Kind,
-- A subtype of a private type, created by a subtype declaration used
-- to declare a subtype of a private type.
- (Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
- Sm (Scope_Depth_Value, Uint)));
+ (Sm (Scope_Depth_Value, Uint)));
Cc (E_Limited_Private_Type, Private_Kind,
-- A limited private type, created by a private type declaration that
@@ -901,9 +885,7 @@ begin -- Gen_IL.Gen.Gen_Entities
(Sm (Scope_Depth_Value, Uint)));
Ab (Incomplete_Kind, Incomplete_Or_Private_Kind,
- (Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
- Sm (Non_Limited_View, Node_Id)));
+ (Sm (Non_Limited_View, Node_Id)));
Cc (E_Incomplete_Type, Incomplete_Kind,
-- An incomplete type, created by an incomplete type declaration
@@ -915,8 +897,6 @@ begin -- Gen_IL.Gen.Gen_Entities
Ab (Concurrent_Kind, Composite_Kind,
(Sm (Corresponding_Record_Type, Node_Id),
- Sm (Direct_Primitive_Operations, Elist_Id,
- Pre => "Is_Tagged_Type (N)"),
Sm (First_Entity, Node_Id),
Sm (First_Private_Entity, Node_Id),
Sm (Last_Entity, Node_Id),
@@ -1200,7 +1180,7 @@ begin -- Gen_IL.Gen.Gen_Entities
-- for the body of a protected entry family.
(Sm (Entry_Index_Constant, Node_Id)));
- Cc (E_Exception, Entity_Kind,
+ Cc (E_Exception, Exception_Or_Object_Kind,
-- An exception created by an exception declaration. The exception
-- itself uses E_Exception for the Ekind, the implicit type that is
-- created to represent its type uses the Ekind E_Exception_Type.
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index 26fc069..2427a1e 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -31,7 +31,8 @@ procedure Gen_IL.Gen.Gen_Nodes is
renames Create_Abstract_Node_Type;
procedure Cc -- Short for "ConCrete"
(T : Concrete_Node; Parent : Abstract_Type;
- Fields : Field_Sequence := No_Fields)
+ Fields : Field_Sequence := No_Fields;
+ Nmake_Assert : String := "")
renames Create_Concrete_Node_Type;
function Sy -- Short for "Syntactic"
@@ -390,7 +391,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Ab (N_Subprogram_Call, N_Subexpr,
(Sm (Controlling_Argument, Node_Id),
- Sm (Do_Tag_Check, Flag),
Sm (First_Named_Actual, Node_Id),
Sm (Is_Elaboration_Checks_OK_Node, Flag),
Sm (Is_Elaboration_Warnings_OK_Node, Flag),
@@ -553,7 +553,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Do_Discriminant_Check, Flag),
Sm (Do_Length_Check, Flag),
Sm (Do_Overflow_Check, Flag),
- Sm (Do_Tag_Check, Flag),
Sm (Float_Truncate, Flag),
Sm (Rounded_Result, Flag)));
@@ -564,7 +563,12 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Subtype_Mark, Node_Id, Default_Empty),
Sy (Expression, Node_Id, Default_Empty),
Sm (Kill_Range_Check, Flag),
- Sm (No_Truncation, Flag)));
+ Sm (No_Truncation, Flag)),
+ Nmake_Assert => "True or else Nkind (Expression) /= N_Unchecked_Type_Conversion");
+-- Nmake_Assert => "Nkind (Expression) /= N_Unchecked_Type_Conversion");
+ -- Assert that we don't have unchecked conversions of unchecked
+ -- conversions; if Expression might be an unchecked conversion,
+ -- then Tbuild.Unchecked_Convert_To should be used.
Cc (N_Subtype_Indication, N_Has_Etype,
(Sy (Subtype_Mark, Node_Id, Default_Empty),
@@ -573,7 +577,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
Ab (N_Declaration, Node_Kind);
-- Note: this includes all constructs normally thought of as declarations
- -- except those which are separately grouped as later declarations.
+ -- except those that are separately grouped in N_Later_Decl_Item.
Cc (N_Component_Declaration, N_Declaration,
(Sy (Defining_Identifier, Node_Id),
@@ -949,7 +953,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sm (Componentwise_Assignment, Flag),
Sm (Do_Discriminant_Check, Flag),
Sm (Do_Length_Check, Flag),
- Sm (Do_Tag_Check, Flag),
Sm (Forwards_OK, Flag),
Sm (Has_Target_Names, Flag),
Sm (Is_Elaboration_Checks_OK_Node, Flag),
@@ -1056,7 +1059,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Expression, Node_Id, Default_Empty),
Sm (By_Ref, Flag),
Sm (Comes_From_Extended_Return_Statement, Flag),
- Sm (Do_Tag_Check, Flag),
Sm (Procedure_To_Call, Node_Id),
Sm (Return_Statement_Entity, Node_Id),
Sm (Storage_Pool, Node_Id)));
@@ -1065,7 +1067,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Return_Object_Declarations, List_Id),
Sy (Handled_Statement_Sequence, Node_Id, Default_Empty),
Sm (By_Ref, Flag),
- Sm (Do_Tag_Check, Flag),
Sm (Procedure_To_Call, Node_Id),
Sm (Return_Statement_Entity, Node_Id),
Sm (Storage_Pool, Node_Id)));
@@ -1342,7 +1343,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Defining_Identifier, Node_Id),
Sy (Discrete_Subtype_Definition, Node_Id, Default_Empty)));
- Cc (N_Exception_Declaration, Node_Kind,
+ Cc (N_Exception_Declaration, N_Declaration,
(Sy (Defining_Identifier, Node_Id),
Sm (Expression, Node_Id),
Sm (More_Ids, Flag),
@@ -1487,7 +1488,6 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sy (Parameter_Type, Node_Id),
Sy (Expression, Node_Id, Default_Empty),
Sm (Default_Expression, Node_Id),
- Sm (Do_Accessibility_Check, Flag),
Sm (More_Ids, Flag),
Sm (Prev_Ids, Flag)));
diff --git a/gcc/ada/gen_il-gen.adb b/gcc/ada/gen_il-gen.adb
index 0f3698e..94f7c9c 100644
--- a/gcc/ada/gen_il-gen.adb
+++ b/gcc/ada/gen_il-gen.adb
@@ -47,9 +47,10 @@ package body Gen_IL.Gen is
All_Entities : constant Type_Vector := To_Vector (Entity_Kind, Length => 1);
procedure Create_Type
- (T : Node_Or_Entity_Type;
- Parent : Opt_Abstract_Type;
- Fields : Field_Sequence);
+ (T : Node_Or_Entity_Type;
+ Parent : Opt_Abstract_Type;
+ Fields : Field_Sequence;
+ Nmake_Assert : String);
-- Called by the Create_..._Type procedures exported by this package to
-- create an entry in the Types_Table.
@@ -107,9 +108,10 @@ package body Gen_IL.Gen is
-----------------
procedure Create_Type
- (T : Node_Or_Entity_Type;
- Parent : Opt_Abstract_Type;
- Fields : Field_Sequence)
+ (T : Node_Or_Entity_Type;
+ Parent : Opt_Abstract_Type;
+ Fields : Field_Sequence;
+ Nmake_Assert : String)
is
begin
Check_Type (T);
@@ -132,7 +134,8 @@ package body Gen_IL.Gen is
new Type_Info'
(Is_Union => False, Parent => Parent,
Children | Concrete_Descendants => Type_Vectors.Empty_Vector,
- First | Last | Fields => <>); -- filled in later
+ First | Last | Fields => <>, -- filled in later
+ Nmake_Assert => new String'(Nmake_Assert));
if Parent /= No_Type then
Append (Type_Table (Parent).Children, T);
@@ -215,7 +218,7 @@ package body Gen_IL.Gen is
(T : Abstract_Node;
Fields : Field_Sequence := No_Fields) is
begin
- Create_Type (T, Parent => No_Type, Fields => Fields);
+ Create_Type (T, Parent => No_Type, Fields => Fields, Nmake_Assert => "");
end Create_Root_Node_Type;
-------------------------------
@@ -227,7 +230,7 @@ package body Gen_IL.Gen is
Fields : Field_Sequence := No_Fields)
is
begin
- Create_Type (T, Parent, Fields);
+ Create_Type (T, Parent, Fields, Nmake_Assert => "");
end Create_Abstract_Node_Type;
-------------------------------
@@ -236,10 +239,11 @@ package body Gen_IL.Gen is
procedure Create_Concrete_Node_Type
(T : Concrete_Node; Parent : Abstract_Type;
- Fields : Field_Sequence := No_Fields)
+ Fields : Field_Sequence := No_Fields;
+ Nmake_Assert : String := "")
is
begin
- Create_Type (T, Parent, Fields);
+ Create_Type (T, Parent, Fields, Nmake_Assert);
end Create_Concrete_Node_Type;
-----------------------------
@@ -250,7 +254,7 @@ package body Gen_IL.Gen is
(T : Abstract_Entity;
Fields : Field_Sequence := No_Fields) is
begin
- Create_Type (T, Parent => No_Type, Fields => Fields);
+ Create_Type (T, Parent => No_Type, Fields => Fields, Nmake_Assert => "");
end Create_Root_Entity_Type;
---------------------------------
@@ -262,7 +266,7 @@ package body Gen_IL.Gen is
Fields : Field_Sequence := No_Fields)
is
begin
- Create_Type (T, Parent, Fields);
+ Create_Type (T, Parent, Fields, Nmake_Assert => "");
end Create_Abstract_Entity_Type;
---------------------------------
@@ -274,7 +278,7 @@ package body Gen_IL.Gen is
Fields : Field_Sequence := No_Fields)
is
begin
- Create_Type (T, Parent, Fields);
+ Create_Type (T, Parent, Fields, Nmake_Assert => "");
end Create_Concrete_Entity_Type;
------------------
@@ -352,7 +356,7 @@ package body Gen_IL.Gen is
Image (Field);
end if;
- if Pre /= Field_Table (Field).Pre.all then
+ if Pre_Set /= Field_Table (Field).Pre_Set.all then
raise Illegal with
"mismatched extra setter-only preconditions for " &
Image (Field);
@@ -2561,6 +2565,11 @@ package body Gen_IL.Gen is
end;
end if;
+ if Type_Table (T).Nmake_Assert.all /= "" then
+ Put (S, "pragma Assert (" &
+ Type_Table (T).Nmake_Assert.all & ");" & LF);
+ end if;
+
Put (S, "return N;" & LF);
Decrease_Indent (S, 3);
@@ -2628,6 +2637,7 @@ package body Gen_IL.Gen is
Increase_Indent (B, 3);
Put (B, "-- This package is automatically generated." & LF & LF);
+ Put (B, "pragma Style_Checks (""M200"");" & LF);
Put_Make_Bodies (B, Node_Kind);
diff --git a/gcc/ada/gen_il-gen.ads b/gcc/ada/gen_il-gen.ads
index 34ce2d6..1d24ebf 100644
--- a/gcc/ada/gen_il-gen.ads
+++ b/gcc/ada/gen_il-gen.ads
@@ -102,9 +102,12 @@ package Gen_IL.Gen is
procedure Create_Concrete_Node_Type
(T : Concrete_Node; Parent : Abstract_Type;
- Fields : Field_Sequence := No_Fields);
+ Fields : Field_Sequence := No_Fields;
+ Nmake_Assert : String := "");
-- Create a concrete node type. Every node is an instance of a concrete
- -- node type.
+ -- node type. Nmake_Assert is an assertion to put in the Make_... function
+ -- in the generated Nmake package. It should be a String that represents a
+ -- Boolean expression.
procedure Create_Root_Entity_Type
(T : Abstract_Entity;
@@ -151,13 +154,14 @@ package Gen_IL.Gen is
-- only for syntactic fields. Flag fields of syntactic nodes always have a
-- default value, which is False unless specified as Default_True. Pre is
-- an additional precondition for the field getter and setter, in addition
- -- to the precondition that asserts that the type has that field. Pre_Get
- -- and Pre_Set are similar to Pre, but for the getter or setter only,
- -- respectively.
+ -- to the precondition that asserts that the type has that field. It should
+ -- be a String that represents a Boolean expression. Pre_Get and Pre_Set
+ -- are similar to Pre, but for the getter or setter only, respectively.
--
-- If multiple calls to these occur for the same Field but different types,
- -- the Field_Type and Pre must match. Default_Value should match for
- -- syntactic fields. See the declaration of Type_Only_Enum for Type_Only.
+ -- the Field_Type, Pre, Pre_Get, and Pre_Set must match. Default_Value
+ -- should match for syntactic fields. See the declaration of Type_Only_Enum
+ -- for Type_Only.
--
-- (The matching Default_Value requirement is a simplification from the
-- earlier hand-written version.)
diff --git a/gcc/ada/gen_il-internals.ads b/gcc/ada/gen_il-internals.ads
index 9c5779b..b8911ec 100644
--- a/gcc/ada/gen_il-internals.ads
+++ b/gcc/ada/gen_il-internals.ads
@@ -104,6 +104,8 @@ package Gen_IL.Internals is
-- includes two or more types.
Fields : Field_Vector;
+
+ Nmake_Assert : String_Access; -- only for concrete node types
end case;
end record;
diff --git a/gcc/ada/gen_il-types.ads b/gcc/ada/gen_il-types.ads
index 6850411..84eb63f 100644
--- a/gcc/ada/gen_il-types.ads
+++ b/gcc/ada/gen_il-types.ads
@@ -140,6 +140,7 @@ package Gen_IL.Types is
Elementary_Kind,
Enumeration_Kind,
Entry_Kind,
+ Exception_Or_Object_Kind,
Fixed_Point_Kind,
Float_Kind,
Formal_Kind,
@@ -166,6 +167,7 @@ package Gen_IL.Types is
Signed_Integer_Kind,
Task_Kind,
Type_Kind,
+ Void_Or_Type_Kind,
-- End of abstract entity types.
diff --git a/gcc/ada/gnat-style.texi b/gcc/ada/gnat-style.texi
index 50adaab..37ce690 100644
--- a/gcc/ada/gnat-style.texi
+++ b/gcc/ada/gnat-style.texi
@@ -1,94 +1,71 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
-
-@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
-@c o
-@c GNAT DOCUMENTATION o
-@c o
-@c G N A T C O D I N G S T Y L E o
-@c o
-@c Copyright (C) 1992-2012, AdaCore o
-@c o
-@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
-
@setfilename gnat-style.info
+@documentencoding UTF-8
+@ifinfo
+@*Generated by Sphinx 4.0.2.@*
+@end ifinfo
+@settitle GNAT Coding Style A Guide for GNAT Developers
+@defindex ge
+@paragraphindent 0
+@exampleindent 4
+@finalout
+@dircategory GNU Ada Tools
+@direntry
+* gnat-style: (gnat-style.info). gnat-style
+@end direntry
-@copying
-Copyright @copyright{} 1992-2012, AdaCore
+@definfoenclose strong,`,'
+@definfoenclose emph,`,'
+@c %**end of header
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts and with no Back-Cover
-Texts. A copy of the license is included in the section entitled
-``GNU Free Documentation License''.
-@end copying
+@copying
+@quotation
+GNAT Coding Style: A Guide for GNAT Developers , Jun 23, 2021
-@settitle GNAT Coding Style
-@setchapternewpage odd
+AdaCore
-@include gcc-common.texi
+Copyright @copyright{} 2008-2021, Free Software Foundation
+@end quotation
-@dircategory Software development
-@direntry
-* gnat-style: (gnat-style). GNAT Coding Style
-@end direntry
-
-@macro syntax{element}
-@t{\element\}
-@end macro
-@c %**end of header
+@end copying
@titlepage
-@titlefont{GNAT Coding Style:}
-@sp 1
-@title A Guide for GNAT Developers
-@subtitle GNAT, The GNU Ada Compiler
-@versionsubtitle
-@author Ada Core Technologies, Inc.
-@page
-@vskip 0pt plus 1filll
-
+@title GNAT Coding Style A Guide for GNAT Developers
@insertcopying
@end titlepage
+@contents
-@raisesections
+@c %** start of user preamble
-@node Top, General, , (dir)
-@comment node-name, next, previous, up
+@c %** end of user preamble
@ifnottex
-@noindent
-GNAT Coding Style@*
-A Guide for GNAT Developers
-@sp 2
-@noindent
-GNAT, The GNU Ada Compiler@*
-
-@noindent
+@node Top
+@top GNAT Coding Style A Guide for GNAT Developers
@insertcopying
@end ifnottex
-
+@c %**start of body
+@anchor{gnat-style doc}@anchor{0}
@menu
-* General::
-* Lexical Elements::
-* Declarations and Types::
-* Expressions and Names::
-* Statements::
-* Subprograms::
-* Packages::
-* Program Structure::
-* GNU Free Documentation License::
-* Index::
+* General::
+* Lexical Elements::
+* Declarations and Types::
+* Expressions and Names::
+* Statements::
+* Subprograms::
+* Packages and Visibility Rules::
+* Program Structure and Compilation Issues::
+* Index::
+
@end menu
-@c -------------------------------------------------------------------------
-@node General, Lexical Elements, Top, Top
-@section General
-@c -------------------------------------------------------------------------
+@node General,Lexical Elements,Top,Top
+@anchor{gnat-style general}@anchor{1}@anchor{gnat-style gnat-coding-style-a-guide-for-gnat-developers}@anchor{2}
+@chapter General
+
-@noindent
Most of GNAT is written in Ada using a consistent style to ensure
readability of the code. This document has been written to help
maintain this consistent style, while having a large group of developers
@@ -97,148 +74,184 @@ work on the compiler.
For the coding style in the C parts of the compiler and run time,
see the GNU Coding Guidelines.
-This document is structured after the @cite{Ada Reference Manual}.
+This document is structured after the Ada Reference Manual.
Those familiar with that document should be able to quickly
lookup style rules for particular constructs.
+@node Lexical Elements,Declarations and Types,General,Top
+@anchor{gnat-style lexical-elements}@anchor{3}
+@chapter Lexical Elements
-@c -------------------------------------------------------------------------
-@node Lexical Elements, Declarations and Types, General, Top
-@section Lexical Elements
-@c -------------------------------------------------------------------------
-@cindex Lexical elements
-
-@subsection Character Set and Separators
-@c -------------------------------------------------------------------------
-@cindex Character set
-@cindex ASCII
-@cindex Separators
-@cindex End-of-line
-@cindex Line length
-@cindex Indentation
-
-@itemize @bullet
-@item
-The character set used should be plain 7-bit ASCII@.
+
+@menu
+* Character Set and Separators::
+* Identifiers::
+* Numeric Literals::
+* Reserved Words::
+* Comments::
+
+@end menu
+
+@node Character Set and Separators,Identifiers,,Lexical Elements
+@anchor{gnat-style character-set-and-separators}@anchor{4}
+@section Character Set and Separators
+
+
+@geindex Character set
+
+@geindex ASCII
+
+@geindex Separators
+
+@geindex End-of-line
+
+@geindex Line length
+
+@geindex Indentation
+
+
+@itemize *
+
+@item
+The character set used should be plain 7-bit ASCII.
The only separators allowed are space and the end-of-line sequence.
No other control character or format effector (such as @code{HT},
-@code{VT}, @code{FF})
+@code{VT}, @code{FF} )
should be used.
The normal end-of-line sequence is used, which may be
@code{LF}, @code{CR/LF} or @code{CR},
depending on the host system. An optional @code{SUB}
-(@code{16#1A#}) may be present as the
+( @code{16#1A#} ) may be present as the
last character in the file on hosts using that character as file terminator.
-@item
+@item
Files that are checked in or distributed should be in host format.
-@item
+@item
A line should never be longer than 79 characters, not counting the line
separator.
-@item
+@item
Lines must not have trailing blanks.
-@item
+@item
Indentation is 3 characters per level for @code{if} statements, loops, and
@code{case} statements.
For exact information on required spacing between lexical
-elements, see file @file{style.adb}.
-@cindex @file{style.adb} file
+elements, see file style.adb.
+
+@geindex style.adb file
@end itemize
+@node Identifiers,Numeric Literals,Character Set and Separators,Lexical Elements
+@anchor{gnat-style identifiers}@anchor{5}
+@section Identifiers
+
-@subsection Identifiers
-@c -------------------------------------------------------------------------
-@itemize @bullet
-@cindex Identifiers
-@item
+@itemize *
+
+@item
Identifiers will start with an upper case letter, and each letter following
an underscore will be upper case.
-@cindex Casing (for identifiers)
+
+@geindex Casing (for identifiers)
+
Short acronyms may be all upper case.
All other letters are lower case.
An exception is for identifiers matching a foreign language. In particular,
-we use all lower case where appropriate for C@.
+we use all lower case where appropriate for C.
-@item
+@item
Use underscores to separate words in an identifier.
-@cindex Underscores
-@item Try to limit your use of abbreviations in identifiers.
+@geindex Underscores
+
+@item
+Try to limit your use of abbreviations in identifiers.
It is ok to make a few abbreviations, explain what they mean, and then
-use them frequently, but don't use lots of obscure abbreviations. An
+use them frequently, but don’t use lots of obscure abbreviations. An
example is the @code{ALI} word which stands for Ada Library
Information and is by convention always written in upper-case when
used in entity names.
-@smallexample @c adanocomment
- procedure Find_ALI_Files;
-@end smallexample
+@example
+procedure Find_ALI_Files;
+@end example
-@item
-Don't use the variable name @code{I}, use @code{J} instead; @code{I} is too
-easily confused with @code{1} in some fonts. Similarly don't use the
+@item
+Don’t use the variable name @code{I}, use @code{J} instead; @code{I} is too
+easily confused with @code{1} in some fonts. Similarly don’t use the
variable @code{O}, which is too easily mistaken for the number @code{0}.
@end itemize
-@subsection Numeric Literals
-@c -------------------------------------------------------------------------
-@cindex Numeric literals
+@node Numeric Literals,Reserved Words,Identifiers,Lexical Elements
+@anchor{gnat-style numeric-literals}@anchor{6}
+@section Numeric Literals
+
+
+
+@itemize *
-@itemize @bullet
-@item
+@item
Numeric literals should include underscores where helpful for
readability.
-@cindex Underscores
-@smallexample
- 1_000_000
- 16#8000_0000#
- 3.14159_26535_89793_23846
-@end smallexample
+@geindex Underscores
+
+@example
+1_000_000
+16#8000_0000#
+3.14159_26535_89793_23846
+@end example
@end itemize
-@subsection Reserved Words
-@c -------------------------------------------------------------------------
-@cindex Reserved words
+@node Reserved Words,Comments,Numeric Literals,Lexical Elements
+@anchor{gnat-style reserved-words}@anchor{7}
+@section Reserved Words
+
+
-@itemize @bullet
-@item
+@itemize *
+
+@item
Reserved words use all lower case.
-@cindex Casing (for reserved words)
-@smallexample @c adanocomment
- return else
-@end smallexample
+@geindex Casing (for reserved words)
+
+@example
+return else
+@end example
-@item
+@item
The words @code{Access}, @code{Delta} and @code{Digits} are
-capitalized when used as @syntax{attribute_designator}.
+capitalized when used as attribute_designator.
@end itemize
-@subsection Comments
-@c -------------------------------------------------------------------------
-@cindex Comments
+@node Comments,,Reserved Words,Lexical Elements
+@anchor{gnat-style comments}@anchor{8}
+@section Comments
-@itemize @bullet
-@item
+
+
+@itemize *
+
+@item
A comment starts with @code{--} followed by two spaces.
-The only exception to this rule (i.e.@: one space is tolerated) is when the
+The only exception to this rule (i.e. one space is tolerated) is when the
comment ends with a single space followed by @code{--}.
It is also acceptable to have only one space between @code{--} and the start
of the comment when the comment is at the end of a line,
after some Ada code.
-@item
+@item
Every sentence in a comment should start with an upper-case letter (including
the first letter of the comment).
-@cindex Casing (in comments)
-@item
-When declarations are commented with ``hanging'' comments, i.e.@:
+@geindex Casing (in comments)
+
+@item
+When declarations are commented with ‘hanging’ comments, i.e.
comments after the declaration, there is no blank line before the
comment, and if it is absolutely necessary to have blank lines within
the comments, e.g. to make paragraph separations within a single comment,
@@ -246,217 +259,232 @@ these blank lines @emph{do} have a @code{--} (unlike the
normal rule, which is to use entirely blank lines for separating
comment paragraphs). The comment starts at same level of indentation
as code it is commenting.
-@cindex Blank lines (in comments)
-@cindex Indentation
-@smallexample @c adanocomment
- z : Integer;
- -- Integer value for storing value of z
- --
- -- The previous line was a blank line.
-@end smallexample
+@geindex Blank lines (in comments)
+
+@geindex Indentation
-@item
+@example
+z : Integer;
+-- Integer value for storing value of z
+--
+-- The previous line was a blank line.
+@end example
+
+@item
Comments that are dubious or incomplete, or that comment on possibly
-wrong or incomplete code, should be preceded or followed by @code{???}@.
+wrong or incomplete code, should be preceded or followed by @code{???}.
-@item
+@item
Comments in a subprogram body must generally be surrounded by blank lines.
An exception is a comment that follows a line containing a single keyword
-(@code{begin}, @code{else}, @code{loop}):
+( @code{begin}, @code{else}, @code{loop} ):
-@smallexample @c adanocomment
-@group
- begin
- -- Comment for the next statement
+@example
+begin
+ -- Comment for the next statement
- A := 5;
+ A := 5;
- -- Comment for the B statement
+ -- Comment for the B statement
- B := 6;
- end;
-@end group
-@end smallexample
+ B := 6;
+end;
+@end example
-@item
+@item
In sequences of statements, comments at the end of the lines should be
aligned.
-@cindex Alignment (in comments)
-@smallexample @c adanocomment
- My_Identifier := 5; -- First comment
- Other_Id := 6; -- Second comment
-@end smallexample
+@geindex Alignment (in comments)
+
+@example
+My_Identifier := 5; -- First comment
+Other_Id := 6; -- Second comment
+@end example
-@item
+@item
Short comments that fit on a single line are @emph{not} ended with a
period. Comments taking more than a line are punctuated in the normal
manner.
-@item
+@item
Comments should focus on @emph{why} instead of @emph{what}.
Descriptions of what subprograms do go with the specification.
-@item
+@item
Comments describing a subprogram spec should specifically mention the
formal argument names. General rule: write a comment that does not
depend on the names of things. The names are supplementary, not
sufficient, as comments.
-@item
+@item
@emph{Do not} put two spaces after periods in comments.
@end itemize
-@c -------------------------------------------------------------------------
-@node Declarations and Types, Expressions and Names, Lexical Elements,Top
-@section Declarations and Types
-@c -------------------------------------------------------------------------
-@cindex Declarations and Types
+@node Declarations and Types,Expressions and Names,Lexical Elements,Top
+@anchor{gnat-style declarations-and-types}@anchor{9}
+@chapter Declarations and Types
+
+
-@itemize @bullet
-@item
+@itemize *
+
+@item
In entity declarations, colons must be surrounded by spaces. Colons
should be aligned.
-@cindex Alignment (in declarations)
-@smallexample @c adanocomment
- Entity1 : Integer;
- My_Entity : Integer;
-@end smallexample
+@geindex Alignment (in declarations)
+
+@example
+Entity1 : Integer;
+My_Entity : Integer;
+@end example
-@item
+@item
Declarations should be grouped in a logical order.
Related groups of declarations may be preceded by a header comment.
-@item
+@item
All local subprograms in a subprogram or package body should be declared
before the first local subprogram body.
-@item
+@item
Do not declare local entities that hide global entities.
-@cindex Hiding of outer entities
-@item
+@geindex Hiding of outer entities
+
+@item
Do not declare multiple variables in one declaration that spans lines.
Start a new declaration on each line, instead.
-@item
-The @syntax{defining_identifier}s of global declarations serve as
-comments of a sort. So don't choose terse names, but look for names
+@item
+The defining_identifiers of global declarations serve as
+comments of a sort. So don’t choose terse names, but look for names
that give useful information instead.
-@item
+@item
Local names can be shorter, because they are used only within
one context, where comments explain their purpose.
-@item
+@item
When starting an initialization or default expression on the line that follows
the declaration line, use 2 characters for indentation.
-@smallexample @c adanocomment
- Entity1 : Integer :=
- Function_Name (Parameters, For_Call);
-@end smallexample
+@example
+Entity1 : Integer :=
+ Function_Name (Parameters, For_Call);
+@end example
-@item
+@item
If an initialization or default expression needs to be continued on subsequent
lines, the continuations should be indented from the start of the expression.
-@smallexample @c adanocomment
- Entity1 : Integer := Long_Function_Name
- (parameters for call);
-@end smallexample
-
+@example
+Entity1 : Integer := Long_Function_Name
+ (parameters for call);
+@end example
@end itemize
+@node Expressions and Names,Statements,Declarations and Types,Top
+@anchor{gnat-style expressions-and-names}@anchor{a}
+@chapter Expressions and Names
+
-@c -------------------------------------------------------------------------
-@node Expressions and Names, Statements, Declarations and Types, Top
-@section Expressions and Names
-@c -------------------------------------------------------------------------
-@cindex Expressions and names
-@itemize @bullet
+@itemize *
-@item
+@item
Every operator must be surrounded by spaces. An exception is that
this rule does not apply to the exponentiation operator, for which
there are no specific layout rules. The reason for this exception
is that sometimes it makes clearer reading to leave out the spaces
around exponentiation.
-@cindex Operators
-@smallexample @c adanocomment
- E := A * B**2 + 3 * (C - D);
-@end smallexample
+@geindex Operators
-@item
+@example
+E := A * B**2 + 3 * (C - D);
+@end example
+
+@item
Use parentheses where they clarify the intended association of operands
with operators:
-@cindex Parenthesization of expressions
-@smallexample @c adanocomment
- (A / B) * C
-@end smallexample
+
+@geindex Parenthesization of expressions
+
+@example
+(A / B) * C
+@end example
@end itemize
-@c -------------------------------------------------------------------------
-@node Statements, Subprograms, Expressions and Names, Top
-@section Statements
-@c -------------------------------------------------------------------------
-@cindex Statements
+@node Statements,Subprograms,Expressions and Names,Top
+@anchor{gnat-style statements}@anchor{b}
+@chapter Statements
+
+
+@menu
+* Simple and Compound Statements::
+* If Statements::
+* Case Statements::
+* Loop Statements::
+* Block Statements::
+
+@end menu
+
+@node Simple and Compound Statements,If Statements,,Statements
+@anchor{gnat-style simple-and-compound-statements}@anchor{c}
+@section Simple and Compound Statements
-@subsection Simple and Compound Statements
-@c -------------------------------------------------------------------------
-@cindex Simple and compound statements
-@itemize @bullet
-@item
+
+@itemize *
+
+@item
Use only one statement or label per line.
-@item
-A longer @syntax{sequence_of_statements} may be divided in logical
+
+@item
+A longer sequence_of_statements may be divided in logical
groups or separated from surrounding code using a blank line.
@end itemize
-@subsection If Statements
-@c -------------------------------------------------------------------------
-@cindex @code{if} statement
+@node If Statements,Case Statements,Simple and Compound Statements,Statements
+@anchor{gnat-style if-statements}@anchor{d}
+@section If Statements
+
-@itemize @bullet
-@item
+
+@itemize *
+
+@item
When the @code{if}, @code{elsif} or @code{else} keywords fit on the
same line with the condition and the @code{then} keyword, then the
statement is formatted as follows:
-@cindex Alignment (in an @code{if} statement)
-
-@smallexample @c adanocomment
-@group
- if @var{condition} then
- ...
- elsif @var{condition} then
- ...
- else
- ...
- end if;
-@end group
-@end smallexample
-
-@noindent
+
+@geindex Alignment (in an if statement)
+
+@example
+if condition then
+ ...
+elsif condition then
+ ...
+else
+ ...
+end if;
+@end example
+
When the above layout is not possible, @code{then} should be aligned
with @code{if}, and conditions should preferably be split before an
@code{and} or @code{or} keyword a follows:
-@smallexample @c adanocomment
-@group
- if @var{long_condition_that_has_to_be_split}
- and then @var{continued_on_the_next_line}
- then
- ...
- end if;
-@end group
-@end smallexample
-
-@noindent
+@example
+if long_condition_that_has_to_be_split
+ and then continued_on_the_next_line
+then
+ ...
+end if;
+@end example
+
The @code{elsif}, @code{else} and @code{end if} always line up with
the @code{if} keyword. The preferred location for splitting the line
is before @code{and} or @code{or}. The continuation of a condition is
@@ -464,287 +492,280 @@ indented with two spaces or as many as needed to make nesting clear.
As an exception, if conditions are closely related either of the
following is allowed:
-@smallexample
-@group
- if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf
- or else
- x = asldkjhalkdsjfhhfd
- or else
- x = asdfadsfadsf
- then
- ...
- end if;
-@end group
-
-@group
- if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf or else
- x = asldkjhalkdsjfhhfd or else
- x = asdfadsfadsf
- then
- ...
- end if;
-@end group
-@end smallexample
-
-@item
-Conditions should use short-circuit forms (@code{and then},
-@code{or else}), except when the operands are boolean variables
+@example
+if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf
+ or else
+ x = asldkjhalkdsjfhhfd
+ or else
+ x = asdfadsfadsf
+then
+ ...
+end if;
+
+if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf or else
+ x = asldkjhalkdsjfhhfd or else
+ x = asdfadsfadsf
+then
+ ...
+end if;
+@end example
+
+@item
+Conditions should use short-circuit forms ( @code{and then},
+@code{or else} ), except when the operands are boolean variables
or boolean constants.
-@cindex Short-circuit forms
-@item
+@geindex Short-circuit forms
+
+@item
Complex conditions in @code{if} statements are indented two characters:
-@cindex Indentation (in @code{if} statements)
-
-@smallexample @c adanocomment
-@group
- if @var{this_complex_condition}
- and then @var{that_other_one}
- and then @var{one_last_one}
- then
- ...
- end if;
-@end group
-@end smallexample
-
-@noindent
+
+@geindex Indentation (in if statements)
+
+@example
+if this_complex_condition
+ and then that_other_one
+ and then one_last_one
+then
+ ...
+end if;
+@end example
+
There are some cases where complex conditionals can be laid out
in manners that do not follow these rules to preserve better
parallelism between branches, e.g.
-@smallexample @c adanocomment
-@group
- if xyz.abc (gef) = 'c'
- or else
- xyz.abc (gef) = 'x'
- then
- ...
- end if;
-@end group
-@end smallexample
+@example
+if xyz.abc (gef) = 'c'
+ or else
+ xyz.abc (gef) = 'x'
+then
+ ...
+end if;
+@end example
-
-@item
+@item
Every @code{if} block is preceded and followed by a blank line, except
-where it begins or ends a @syntax{sequence_of_statements}.
-@cindex Blank lines (in an @code{if} statement)
+where it begins or ends a sequence_of_statements.
+
+@geindex Blank lines (in an if statement)
-@smallexample @c adanocomment
-@group
- A := 5;
+@example
+A := 5;
- if A = 5 then
- null;
- end if;
+if A = 5 then
+ null;
+end if;
- A := 6;
-@end group
-@end smallexample
+A := 6;
+@end example
@end itemize
-@subsection Case Statements
-@cindex @code{case} statements
+@node Case Statements,Loop Statements,If Statements,Statements
+@anchor{gnat-style case-statements}@anchor{e}
+@section Case Statements
+
+
+
+@itemize *
-@itemize @bullet
-@item
+@item
Layout is as below. For long @code{case} statements, the extra indentation
can be saved by aligning the @code{when} clauses with the opening @code{case}.
-@smallexample @c adanocomment
-@group
- case @var{expression} is
- when @var{condition} =>
- ...
- when @var{condition} =>
- ...
- end case;
-@end group
-@end smallexample
+@example
+case expression is
+ when condition =>
+ ...
+ when condition =>
+ ...
+end case;
+@end example
@end itemize
-@subsection Loop Statements
-@cindex Loop statements
+@node Loop Statements,Block Statements,Case Statements,Statements
+@anchor{gnat-style loop-statements}@anchor{f}
+@section Loop Statements
+
+
-@itemize @bullet
-@item
+@itemize *
+
+@item
When possible, have @code{for} or @code{while} on one line with the
condition and the @code{loop} keyword.
-@smallexample @c adanocomment
-@group
- for J in S'Range loop
- ...
- end loop;
-@end group
-@end smallexample
-
-@noindent
-If the condition is too long, split the condition (see ``If
-statements'' above) and align @code{loop} with the @code{for} or
+@example
+for J in S'Range loop
+ ...
+end loop;
+@end example
+
+If the condition is too long, split the condition (see ‘If
+statements’ above) and align @code{loop} with the @code{for} or
@code{while} keyword.
-@cindex Alignment (in a loop statement)
-
-@smallexample @c adanocomment
-@group
- while @var{long_condition_that_has_to_be_split}
- and then @var{continued_on_the_next_line}
- loop
- ...
- end loop;
-@end group
-@end smallexample
-
-@noindent
-If the @syntax{loop_statement} has an identifier, it is laid out as follows:
-
-@smallexample @c adanocomment
-@group
- Outer : while not @var{condition} loop
- ...
- end Outer;
-@end group
-@end smallexample
+
+@geindex Alignment (in a loop statement)
+
+@example
+while long_condition_that_has_to_be_split
+ and then continued_on_the_next_line
+loop
+ ...
+end loop;
+@end example
+
+If the loop_statement has an identifier, it is laid out as follows:
+
+@example
+Outer : while not condition loop
+ ...
+end Outer;
+@end example
@end itemize
-@subsection Block Statements
-@cindex Block statement
+@node Block Statements,,Loop Statements,Statements
+@anchor{gnat-style block-statements}@anchor{10}
+@section Block Statements
+
+
+
+@itemize *
-@itemize @bullet
-@item
+@item
The @code{declare} (optional), @code{begin} and @code{end} words
-are aligned, except when the @syntax{block_statement} is named. There
+are aligned, except when the block_statement is named. There
is a blank line before the @code{begin} keyword:
-@cindex Alignment (in a block statement)
-@smallexample @c adanocomment
-@group
- Some_Block : declare
- ...
+@geindex Alignment (in a block statement)
- begin
- ...
- end Some_Block;
-@end group
-@end smallexample
+@example
+Some_Block : declare
+ ...
+begin
+ ...
+end Some_Block;
+@end example
@end itemize
-@c -------------------------------------------------------------------------
-@node Subprograms, Packages, Statements, Top
-@section Subprograms
-@c -------------------------------------------------------------------------
-@cindex Subprograms
+@node Subprograms,Packages and Visibility Rules,Statements,Top
+@anchor{gnat-style subprograms}@anchor{11}
+@chapter Subprograms
-@subsection Subprogram Declarations
-@c -------------------------------------------------------------------------
-@itemize @bullet
-@item
+@menu
+* Subprogram Declarations::
+* Subprogram Bodies::
+
+@end menu
+
+@node Subprogram Declarations,Subprogram Bodies,,Subprograms
+@anchor{gnat-style subprogram-declarations}@anchor{12}
+@section Subprogram Declarations
+
+
+
+@itemize *
+
+@item
Do not write the @code{in} for parameters.
-@smallexample @c adanocomment
- function Length (S : String) return Integer;
-@end smallexample
+@example
+function Length (S : String) return Integer;
+@end example
-@item
+@item
When the declaration line for a procedure or a function is too long to fit
the entire declaration (including the keyword procedure or function) on a
single line, then fold it, putting a single parameter on a line, aligning
the colons, as in:
-@smallexample @c adanocomment
-@group
- procedure Set_Heading
- (Source : String;
- Count : Natural;
- Pad : Character := Space;
- Fill : Boolean := True);
-@end group
-@end smallexample
-
-@noindent
+@example
+procedure Set_Heading
+ (Source : String;
+ Count : Natural;
+ Pad : Character := Space;
+ Fill : Boolean := True);
+@end example
+
In the case of a function, if the entire spec does not fit on one line, then
the return may appear after the last parameter, as in:
-@smallexample @c adanocomment
-@group
- function Head
- (Source : String;
- Count : Natural;
- Pad : Character := Space) return String;
-@end group
-@end smallexample
+@example
+function Head
+ (Source : String;
+ Count : Natural;
+ Pad : Character := Space) return String;
+@end example
-@noindent
Or it may appear on its own as a separate line. This form is preferred when
putting the return on the same line as the last parameter would result in
an overlong line. The return type may optionally be aligned with the types
of the parameters (usually we do this aligning if it results only in a small
-number of extra spaces, and otherwise we don't attempt to align). So two
+number of extra spaces, and otherwise we don’t attempt to align). So two
alternative forms for the above spec are:
-@smallexample @c adanocomment
-@group
- function Head
- (Source : String;
- Count : Natural;
- Pad : Character := Space)
- return String;
-
- function Head
- (Source : String;
- Count : Natural;
- Pad : Character := Space)
- return String;
-@end group
-@end smallexample
-
+@example
+function Head
+ (Source : String;
+ Count : Natural;
+ Pad : Character := Space)
+ return String;
+
+function Head
+ (Source : String;
+ Count : Natural;
+ Pad : Character := Space)
+ return String;
+@end example
@end itemize
-@subsection Subprogram Bodies
-@c -------------------------------------------------------------------------
-@cindex Subprogram bodies
+@node Subprogram Bodies,,Subprogram Declarations,Subprograms
+@anchor{gnat-style subprogram-bodies}@anchor{13}
+@section Subprogram Bodies
+
+
-@itemize @bullet
-@item
+@itemize *
+
+@item
Function and procedure bodies should usually be sorted alphabetically. Do
not attempt to sort them in some logical order by functionality. For a
sequence of subprogram specs, a general alphabetical sorting is also
usually appropriate, but occasionally it makes sense to group by major
function, with appropriate headers.
-@item
+@item
All subprograms have a header giving the function name, with the following
format:
-@smallexample @c adanocomment
-@group
- -----------------
- -- My_Function --
- -----------------
+@example
+-----------------
+-- My_Function --
+-----------------
- procedure My_Function is
- begin
- ...
- end My_Function;
-@end group
-@end smallexample
+procedure My_Function is
+begin
+ ...
+end My_Function;
+@end example
-@noindent
Note that the name in the header is preceded by a single space,
not two spaces as for other comments. These headers are used on
nested subprograms as well as outer level subprograms. They may
also be used as headers for sections of comments, or collections
of declarations that are related.
-@item
-Every subprogram body must have a preceding @syntax{subprogram_declaration},
+@item
+Every subprogram body must have a preceding subprogram_declaration,
which includes proper client documentation so that you do not need to
read the subprogram body in order to understand what the subprogram does and
how to call it. All subprograms should be documented, without exceptions.
-@item
-@cindex Blank lines (in subprogram bodies)
+@geindex Blank lines (in subprogram bodies)
+
+@item
A sequence of declarations may optionally be separated from the following
begin by a blank line. Just as we optionally allow blank lines in general
between declarations, this blank line should be present only if it improves
@@ -752,22 +773,20 @@ readability. Generally we avoid this blank line if the declarative part is
small (one or two lines) and the body has no blank lines, and we include it
if the declarative part is long or if the body has blank lines.
-@item
+@item
If the declarations in a subprogram contain at least one nested
subprogram body, then just before the @code{begin} of the enclosing
subprogram, there is a comment line and a blank line:
-@smallexample @c adanocomment
-@group
- -- Start of processing for @var{Enclosing_Subprogram}
+@example
+-- Start of processing for Enclosing_Subprogram
- begin
- ...
- end @var{Enclosing_Subprogram};
-@end group
-@end smallexample
+begin
+ ...
+end Enclosing_Subprogram;
+@end example
-@item
+@item
When nested subprograms are present, variables that are referenced by any
nested subprogram should precede the nested subprogram specs. For variables
that are not referenced by nested procedures, the declarations can either also
@@ -775,180 +794,646 @@ be before any of the nested subprogram specs (this is the old style, more
generally used). Or then can come just before the begin, with a header. The
following example shows the two possible styles:
-@smallexample @c adanocomment
-@group
- procedure Style1 is
- Var_Referenced_In_Nested : Integer;
- Var_Referenced_Only_In_Style1 : Integer;
-
- proc Nested;
- -- Comments ...
-
+@example
+procedure Style1 is
+ Var_Referenced_In_Nested : Integer;
+ Var_Referenced_Only_In_Style1 : Integer;
- ------------
- -- Nested --
- ------------
+ proc Nested;
+ -- Comments ...
- procedure Nested is
- begin
- ...
- end Nested;
+ ------------
+ -- Nested --
+ ------------
- -- Start of processing for Style1
-
- begin
- ...
- end Style1;
+ procedure Nested is
+ begin
+ ...
+ end Nested;
-@end group
+-- Start of processing for Style1
-@group
- procedure Style2 is
- Var_Referenced_In_Nested : Integer;
+begin
+ ...
+end Style1;
- proc Nested;
- -- Comments ...
+procedure Style2 is
+ Var_Referenced_In_Nested : Integer;
- ------------
- -- Nested --
- ------------
+ proc Nested;
+ -- Comments ...
- procedure Nested is
- begin
- ...
- end Nested;
+ ------------
+ -- Nested --
+ ------------
- -- Local variables
+ procedure Nested is
+ begin
+ ...
+ end Nested;
- Var_Referenced_Only_In_Style2 : Integer;
+ -- Local variables
- -- Start of processing for Style2
+ Var_Referenced_Only_In_Style2 : Integer;
- begin
- ...
- end Style2;
+-- Start of processing for Style2
-@end group
-@end smallexample
+begin
+ ...
+end Style2;
+@end example
-@noindent
For new code, we generally prefer Style2, but we do not insist on
modifying all legacy occurrences of Style1, which is still much
more common in the sources.
-
@end itemize
+@node Packages and Visibility Rules,Program Structure and Compilation Issues,Subprograms,Top
+@anchor{gnat-style packages-and-visibility-rules}@anchor{14}
+@chapter Packages and Visibility Rules
+
-@c -------------------------------------------------------------------------
-@node Packages, Program Structure, Subprograms, Top
-@section Packages and Visibility Rules
-@c -------------------------------------------------------------------------
-@cindex Packages
-@itemize @bullet
-@item
+@itemize *
+
+@item
All program units and subprograms have their name at the end:
-@smallexample @c adanocomment
-@group
- package P is
- ...
- end P;
-@end group
-@end smallexample
+@example
+package P is
+ ...
+end P;
+@end example
-@item
-We will use the style of @code{use}-ing @code{with}-ed packages, with
+@item
+We will use the style of @code{use} -ing @code{with} -ed packages, with
the context clauses looking like:
-@cindex @code{use} clauses
-@smallexample @c adanocomment
-@group
- with A; use A;
- with B; use B;
-@end group
-@end smallexample
+@geindex use clauses
+
+@example
+with A; use A;
+with B; use B;
+@end example
-@item
+@item
Names declared in the visible part of packages should be
-unique, to prevent name clashes when the packages are @code{use}d.
-@cindex Name clash avoidance
-
-@smallexample @c adanocomment
-@group
- package Entity is
- type Entity_Kind is ...;
- ...
- end Entity;
-@end group
-@end smallexample
-
-@item
+unique, to prevent name clashes when the packages are @code{use} d.
+
+@geindex Name clash avoidance
+
+@example
+package Entity is
+ type Entity_Kind is ...;
+ ...
+end Entity;
+@end example
+
+@item
After the file header comment, the context clause and unit specification
-should be the first thing in a @syntax{program_unit}.
+should be the first thing in a program_unit.
-@item
+@item
Preelaborate, Pure and Elaborate_Body pragmas should be added right after the
package name, indented an extra level and using the parameterless form:
-@smallexample @c adanocomment
-@group
- package Preelaborate_Package is
- pragma Preelaborate;
- ...
- end Preelaborate_Package;
-@end group
-@end smallexample
-
+@example
+package Preelaborate_Package is
+ pragma Preelaborate;
+ ...
+end Preelaborate_Package;
+@end example
@end itemize
-@c -------------------------------------------------------------------------
-@node Program Structure, GNU Free Documentation License, Packages, Top
-@section Program Structure and Compilation Issues
-@c -------------------------------------------------------------------------
-@cindex Program structure
+@node Program Structure and Compilation Issues,Index,Packages and Visibility Rules,Top
+@anchor{gnat-style program-structure-and-compilation-issues}@anchor{15}
+@chapter Program Structure and Compilation Issues
-@itemize @bullet
-@item
-Every GNAT source file must be compiled with the @option{-gnatg}
+
+
+@itemize *
+
+@item
+Every GNAT source file must be compiled with the @code{-gnatg}
switch to check the coding style.
(Note that you should look at
-@file{style.adb} to see the lexical rules enforced by
-@option{-gnatg}).
-@cindex @option{-gnatg} option (to gcc)
-@cindex @file{style.adb} file
+style.adb to see the lexical rules enforced by @code{-gnatg} ).
+
+@geindex -gnatg option (to gcc)
+
+@geindex style.adb file
-@item
+@item
Each source file should contain only one compilation unit.
-@item
+@item
Filenames should be 8 or fewer characters, followed by the @code{.adb}
extension for a body or @code{.ads} for a spec.
-@cindex File name length
-@item
-Unit names should be distinct when ``krunch''ed to 8 characters
-(see @file{krunch.ads}) and the filenames should match the unit name,
+@geindex File name length
+
+@item
+Unit names should be distinct when ‘krunch’ed to 8 characters
+(see krunch.ads) and the filenames should match the unit name,
except that they are all lower case.
-@cindex @file{krunch.ads} file
+
+@geindex krunch.ads file
@end itemize
+@menu
+* GNU Free Documentation License::
+
+@end menu
-@c **********************************
-@c * GNU Free Documentation License *
-@c **********************************
-@node GNU Free Documentation License,Index, Program Structure, Top
-@unnumberedsec GNU Free Documentation License
-@set nodefaultgnufreedocumentationlicensenode
-@include fdl.texi
-@c GNU Free Documentation License
-@cindex GNU Free Documentation License
+@node GNU Free Documentation License,,,Program Structure and Compilation Issues
+@anchor{share/gnu_free_documentation_license doc}@anchor{16}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{17}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{18}
+@section GNU Free Documentation License
+
+
+Version 1.3, 3 November 2008
+
+Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc
+@indicateurl{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+@strong{Preamble}
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document “free” in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of “copyleft”, which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@strong{1. APPLICABILITY AND DEFINITIONS}
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The @strong{Document}, below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as “@strong{you}”. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A “@strong{Modified Version}” of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A “@strong{Secondary Section}” is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document’s overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The “@strong{Invariant Sections}” are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The “@strong{Cover Texts}” are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A “@strong{Transparent}” copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not “Transparent” is called @strong{Opaque}.
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The “@strong{Title Page}” means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, “Title Page” means
+the text near the most prominent appearance of the work’s title,
+preceding the beginning of the body of the text.
+
+The “@strong{publisher}” means any person or entity that distributes
+copies of the Document to the public.
+
+A section “@strong{Entitled XYZ}” means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as “@strong{Acknowledgements}”,
+“@strong{Dedications}”, “@strong{Endorsements}”, or “@strong{History}”.)
+To “@strong{Preserve the Title}”
+of such a section when you modify the Document means that it remains a
+section “Entitled XYZ” according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@strong{2. VERBATIM COPYING}
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@strong{3. COPYING IN QUANTITY}
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document’s license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@strong{4. MODIFICATIONS}
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+
+@enumerate A
+
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document’s license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled “History”, Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled “History” in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the “History” section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled “Acknowledgements” or “Dedications”,
+Preserve the Title of the section, and preserve in the section all
+the substance and tone of each of the contributor acknowledgements
+and/or dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled “Endorsements”. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled “Endorsements”
+or to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version’s license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled “Endorsements”, provided it contains
+nothing but endorsements of your Modified Version by various
+parties—for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@strong{5. COMBINING DOCUMENTS}
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled “History”
+in the various original documents, forming one section Entitled
+“History”; likewise combine any sections Entitled “Acknowledgements”,
+and any sections Entitled “Dedications”. You must delete all sections
+Entitled “Endorsements”.
+
+@strong{6. COLLECTIONS OF DOCUMENTS}
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@strong{7. AGGREGATION WITH INDEPENDENT WORKS}
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an “aggregate” if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation’s users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document’s Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@strong{8. TRANSLATION}
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled “Acknowledgements”,
+“Dedications”, or “History”, the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@strong{9. TERMINATION}
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@strong{10. FUTURE REVISIONS OF THIS LICENSE}
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@indicateurl{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License “or any later version” applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy’s public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@strong{11. RELICENSING}
+
+“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+“Massive Multiauthor Collaboration” (or “MMC”) contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+“Incorporate” means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is “eligible for relicensing” if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@strong{ADDENDUM: How to use this License for your documents}
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@quotation
+
+Copyright © YEAR YOUR NAME.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+A copy of the license is included in the section entitled “GNU
+Free Documentation License”.
+@end quotation
-@node Index,,GNU Free Documentation License, Top
-@unnumberedsec Index
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the “with … Texts.” line with this:
-@printindex cp
+@quotation
+
+with the Invariant Sections being LIST THEIR TITLES, with the
+Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+@end quotation
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@node Index,,Program Structure and Compilation Issues,Top
+@unnumbered Index
+
+
+@printindex ge
-@contents
+@c %**end of body
@bye
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index 59b9595..6f65d74 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -67,7 +67,6 @@ with Sem_Type;
with Set_Targ;
with Sinfo; use Sinfo;
with Sinfo.Nodes; use Sinfo.Nodes;
-with Sinfo.Utils; use Sinfo.Utils;
with Sinput; use Sinput;
with Sinput.L; use Sinput.L;
with Snames; use Snames;
@@ -146,12 +145,6 @@ procedure Gnat1drv is
-- Start of processing for Adjust_Global_Switches
begin
- -- Define pragma GNAT_Annotate as an alias of pragma Annotate, to be
- -- able to work around bootstrap limitations with the old syntax of
- -- pragma Annotate, and use pragma GNAT_Annotate in compiler sources
- -- when needed.
-
- Map_Pragma_Name (From => Name_Gnat_Annotate, To => Name_Annotate);
-- -gnatd_U disables prepending error messages with "error:"
@@ -1294,29 +1287,6 @@ begin
Exit_Program (E_Errors);
end if;
- -- Set Generate_Code on main unit and its spec. We do this even if are
- -- not generating code, since Lib-Writ uses this to determine which
- -- units get written in the ali file.
-
- Set_Generate_Code (Main_Unit);
-
- -- If we have a corresponding spec, and it comes from source or it is
- -- not a generated spec for a child subprogram body, then we need object
- -- code for the spec unit as well.
-
- if Nkind (Unit (Main_Unit_Node)) in N_Unit_Body
- and then not Acts_As_Spec (Main_Unit_Node)
- then
- if Nkind (Unit (Main_Unit_Node)) = N_Subprogram_Body
- and then not Comes_From_Source (Library_Unit (Main_Unit_Node))
- then
- null;
- else
- Set_Generate_Code
- (Get_Cunit_Unit_Number (Library_Unit (Main_Unit_Node)));
- end if;
- end if;
-
-- Case of no code required to be generated, exit indicating no error
if Original_Operating_Mode = Check_Syntax then
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 79f8bb3..349586e 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -3,7 +3,7 @@
@setfilename gnat_rm.info
@documentencoding UTF-8
@ifinfo
-@*Generated by Sphinx 1.4.6.@*
+@*Generated by Sphinx 4.0.2.@*
@end ifinfo
@settitle GNAT Reference Manual
@defindex ge
@@ -21,7 +21,7 @@
@copying
@quotation
-GNAT Reference Manual , Apr 12, 2021
+GNAT Reference Manual , Jun 23, 2021
AdaCore
@@ -58,8 +58,8 @@ AdaCore
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being "GNAT Reference
-Manual", and with no Back-Cover Texts. A copy of the license is
+Invariant Sections, with the Front-Cover Texts being “GNAT Reference
+Manual”, and with no Back-Cover Texts. A copy of the license is
included in the section entitled @ref{1,,GNU Free Documentation License}.
@menu
@@ -320,7 +320,7 @@ Implementation Defined Aspects
* Aspect Initializes::
* Aspect Inline_Always::
* Aspect Invariant::
-* Aspect Invariant'Class::
+* Aspect Invariant’Class::
* Aspect Iterable::
* Aspect Linker_Section::
* Aspect Lock_Free::
@@ -557,7 +557,7 @@ Implementation Advice
* RM 3.5.5(8); Enumeration Values: RM 3 5 5 8 Enumeration Values.
* RM 3.5.7(17); Float Types: RM 3 5 7 17 Float Types.
* RM 3.6.2(11); Multidimensional Arrays: RM 3 6 2 11 Multidimensional Arrays.
-* RM 9.6(30-31); Duration'Small: RM 9 6 30-31 Duration'Small.
+* RM 9.6(30-31); Duration’Small: RM 9 6 30-31 Duration’Small.
* RM 10.2.1(12); Consistent Representation: RM 10 2 1 12 Consistent Representation.
* RM 11.4.1(19); Exception Information: RM 11 4 1 19 Exception Information.
* RM 11.5(28); Suppression of Checks: RM 11 5 28 Suppression of Checks.
@@ -860,6 +860,7 @@ Implementation of Specific Ada Features
* GNAT Implementation of Shared Passive Packages::
* Code Generation for Array Aggregates::
* The Size of Discriminated Records with Default Discriminants::
+* Image Values For Nonscalar Types::
* Strict Conformance to the Ada Reference Manual::
GNAT Implementation of Tasking
@@ -913,7 +914,7 @@ Implementation-dependent characteristics
@end menu
@node About This Guide,Implementation Defined Pragmas,Top,Top
-@anchor{gnat_rm/about_this_guide about-this-guide}@anchor{2}@anchor{gnat_rm/about_this_guide doc}@anchor{3}@anchor{gnat_rm/about_this_guide gnat-reference-manual}@anchor{4}@anchor{gnat_rm/about_this_guide id1}@anchor{5}
+@anchor{gnat_rm/about_this_guide doc}@anchor{2}@anchor{gnat_rm/about_this_guide about-this-guide}@anchor{3}@anchor{gnat_rm/about_this_guide gnat-reference-manual}@anchor{4}@anchor{gnat_rm/about_this_guide id1}@anchor{5}
@chapter About This Guide
@@ -928,8 +929,8 @@ invoked in Ada 83 compatibility mode.
By default, GNAT assumes Ada 2012,
but you can override with a compiler switch
to explicitly specify the language version.
-(Please refer to the @emph{GNAT User's Guide} for details on these switches.)
-Throughout this manual, references to 'Ada' without a year suffix
+(Please refer to the @emph{GNAT User’s Guide} for details on these switches.)
+Throughout this manual, references to ‘Ada’ without a year suffix
apply to all the Ada versions of the language.
Ada is designed to be highly portable.
@@ -1002,7 +1003,7 @@ of representation clauses and pragmas that is accepted.
@item
@ref{e,,Standard Library Routines}, provides a listing of packages and a
-brief description of the functionality that is provided by Ada's
+brief description of the functionality that is provided by Ada’s
extensive set of standard library routines as implemented by GNAT.
@item
@@ -1024,7 +1025,7 @@ of the specialized needs annexes.
@item
@ref{13,,Implementation of Specific Ada Features}, discusses issues related
-to GNAT's implementation of machine code insertions, tasking, and several
+to GNAT’s implementation of machine code insertions, tasking, and several
other features.
@item
@@ -1118,7 +1119,7 @@ See the following documents for further information on GNAT:
@itemize *
@item
-@cite{GNAT User's Guide for Native Platforms},
+@cite{GNAT User’s Guide for Native Platforms},
which provides information on how to use the
GNAT development environment.
@@ -1154,7 +1155,7 @@ compiler system.
@end itemize
@node Implementation Defined Pragmas,Implementation Defined Aspects,About This Guide,Top
-@anchor{gnat_rm/implementation_defined_pragmas implementation-defined-pragmas}@anchor{7}@anchor{gnat_rm/implementation_defined_pragmas doc}@anchor{19}@anchor{gnat_rm/implementation_defined_pragmas id1}@anchor{1a}
+@anchor{gnat_rm/implementation_defined_pragmas doc}@anchor{19}@anchor{gnat_rm/implementation_defined_pragmas id1}@anchor{1a}@anchor{gnat_rm/implementation_defined_pragmas implementation-defined-pragmas}@anchor{7}
@chapter Implementation Defined Pragmas
@@ -1412,7 +1413,7 @@ end;
@end example
@node Pragma Abstract_State,Pragma Ada_83,Pragma Abort_Defer,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-abstract-state}@anchor{1c}@anchor{gnat_rm/implementation_defined_pragmas id2}@anchor{1d}
+@anchor{gnat_rm/implementation_defined_pragmas id2}@anchor{1c}@anchor{gnat_rm/implementation_defined_pragmas pragma-abstract-state}@anchor{1d}
@section Pragma Abstract_State
@@ -1664,7 +1665,7 @@ rather than rejected to allow common sets of sources to be used
in the two situations.
@node Pragma Annotate,Pragma Assert,Pragma Allow_Integer_Address,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-annotate}@anchor{26}@anchor{gnat_rm/implementation_defined_pragmas id3}@anchor{27}
+@anchor{gnat_rm/implementation_defined_pragmas id3}@anchor{26}@anchor{gnat_rm/implementation_defined_pragmas pragma-annotate}@anchor{27}
@section Pragma Annotate
@@ -1849,7 +1850,7 @@ The pragma applies in both cases to pragmas and aspects with matching
names, e.g. @code{Pre} applies to the Pre aspect, and @code{Precondition}
applies to both the @code{Precondition} pragma
and the aspect @code{Precondition}. Note that the identifiers for
-pragmas Pre_Class and Post_Class are Pre'Class and Post'Class (not
+pragmas Pre_Class and Post_Class are Pre’Class and Post’Class (not
Pre_Class and Post_Class), since these pragmas are intended to be
identical to the corresponding aspects).
@@ -1866,7 +1867,7 @@ The implementation defined policy @code{DISABLE} is like
@code{IGNORE} except that it completely disables semantic
checking of the corresponding pragma or aspect. This is
useful when the pragma or aspect argument references subprograms
-in a with'ed package which is replaced by a dummy package
+in a with’ed package which is replaced by a dummy package
for the final build.
The implementation defined assertion kind @code{Assertions} applies to all
@@ -1966,7 +1967,7 @@ is erroneous so there are no guarantees that this will always be the
case, and it is recommended that these two options not be used together.
@node Pragma Async_Readers,Pragma Async_Writers,Pragma Assume_No_Invalid_Values,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-async-readers}@anchor{2d}@anchor{gnat_rm/implementation_defined_pragmas id4}@anchor{2e}
+@anchor{gnat_rm/implementation_defined_pragmas id4}@anchor{2d}@anchor{gnat_rm/implementation_defined_pragmas pragma-async-readers}@anchor{2e}
@section Pragma Async_Readers
@@ -2124,13 +2125,13 @@ This implementation permission accommodates the notion
of infinities in IEEE floating-point, and corresponds to the
efficient execution mode on most machines. GNAT will not raise
overflow exceptions on these machines; instead it will generate
-infinities and NaN's as defined in the IEEE standard.
+infinities and NaN’s as defined in the IEEE standard.
Generating infinities, although efficient, is not always desirable.
Often the preferable approach is to check for overflow, even at the
(perhaps considerable) expense of run-time performance.
-This can be accomplished by defining your own constrained floating-point subtypes -- i.e., by supplying explicit
-range constraints -- and indeed such a subtype
+This can be accomplished by defining your own constrained floating-point subtypes – i.e., by supplying explicit
+range constraints – and indeed such a subtype
can have the same base range as its base type. For example:
@example
@@ -2326,7 +2327,7 @@ indicating that the necessary attribute for implementation of this
pragma is not available.
@node Pragma Compile_Time_Error,Pragma Compile_Time_Warning,Pragma Common_Object,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-compile-time-error}@anchor{39}@anchor{gnat_rm/implementation_defined_pragmas compile-time-error}@anchor{3a}
+@anchor{gnat_rm/implementation_defined_pragmas compile-time-error}@anchor{39}@anchor{gnat_rm/implementation_defined_pragmas pragma-compile-time-error}@anchor{3a}
@section Pragma Compile_Time_Error
@@ -2369,8 +2370,8 @@ of an error message. If switch @emph{-gnatw_C} is used, a warning is only issued
if the value of the expression is known to be True at compile time, not when
the value of the expression is not known at compile time.
Note that if this pragma is used in a package that
-is with'ed by a client, the client will get the warning even though it
-is issued by a with'ed package (normally warnings in with'ed units are
+is with’ed by a client, the client will get the warning even though it
+is issued by a with’ed package (normally warnings in with’ed units are
suppressed, but this is a special exception to that rule).
One typical use is within a generic where compile time known characteristics
@@ -2380,7 +2381,7 @@ for example that it is not fully implemented.
In previous versions of the compiler, combining @emph{-gnatwe} with
Compile_Time_Warning resulted in a fatal error. Now the compiler always emits
-a warning. You can use @ref{3a,,Pragma Compile_Time_Error} to force the generation of
+a warning. You can use @ref{39,,Pragma Compile_Time_Error} to force the generation of
an error.
@node Pragma Compiler_Unit,Pragma Compiler_Unit_Warning,Pragma Compile_Time_Warning,Implementation Defined Pragmas
@@ -2744,13 +2745,13 @@ must be of one of the following forms:
@strong{function} @code{Fname} @strong{return} T`
@item
-@strong{function} @code{Fname} @strong{return} T'Class
+@strong{function} @code{Fname} @strong{return} T’Class
@item
-@strong{function} @code{Fname} (...) @strong{return} T`
+@strong{function} @code{Fname} (…) @strong{return} T`
@item
-@strong{function} @code{Fname} (...) @strong{return} T'Class
+@strong{function} @code{Fname} (…) @strong{return} T’Class
@end itemize
where @code{T} is a limited record type imported from C++ with pragma
@@ -2759,7 +2760,7 @@ where @code{T} is a limited record type imported from C++ with pragma
The first two forms import the default constructor, used when an object
of type @code{T} is created on the Ada side with no explicit constructor.
The latter two forms cover all the non-default constructors of the type.
-See the GNAT User's Guide for details.
+See the GNAT User’s Guide for details.
If no constructors are imported, it is impossible to create any objects
on the Ada side and the type is implicitly declared abstract.
@@ -2984,7 +2985,7 @@ versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
@node Pragma Depends,Pragma Detect_Blocking,Pragma Default_Storage_Pool,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-depends}@anchor{53}@anchor{gnat_rm/implementation_defined_pragmas id9}@anchor{54}
+@anchor{gnat_rm/implementation_defined_pragmas id9}@anchor{53}@anchor{gnat_rm/implementation_defined_pragmas pragma-depends}@anchor{54}
@section Pragma Depends
@@ -3118,7 +3119,7 @@ pragma Elaboration_Checks (Dynamic | Static);
This is a configuration pragma which specifies the elaboration model to be
used during compilation. For more information on the elaboration models of
-GNAT, consult the chapter on elaboration order handling in the @emph{GNAT User's
+GNAT, consult the chapter on elaboration order handling in the @emph{GNAT User’s
Guide}.
The pragma may appear in the following contexts:
@@ -3130,7 +3131,7 @@ The pragma may appear in the following contexts:
Configuration pragmas file
@item
-Prior to the context clauses of a compilation unit's initial declaration
+Prior to the context clauses of a compilation unit’s initial declaration
@end itemize
Any other placement of the pragma will result in a warning and the effects of
@@ -3585,7 +3586,7 @@ definition. Note that such a package is a child of @code{System}
and thus is considered part of the implementation.
To compile it you will have to use the @emph{-gnatg} switch
for compiling System units, as explained in the
-GNAT User's Guide.
+GNAT User’s Guide.
@node Pragma Extensions_Allowed,Pragma Extensions_Visible,Pragma Extend_System,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-extensions-allowed}@anchor{64}
@@ -3662,10 +3663,9 @@ Casing on composite values (aka pattern matching)
The selector for a case statement may be of a composite type, subject to
some restrictions (described below). Aggregate syntax is used for choices
-of such a case statement; however, in cases where a "normal" aggregate would
+of such a case statement; however, in cases where a “normal” aggregate would
require a discrete value, a discrete subtype may be used instead; box
-notation can also be used to match all values (but currently only
-for discrete subcomponents).
+notation can also be used to match all values.
Consider this example:
@@ -3694,18 +3694,18 @@ then Do_That will be called; otherwise, Do_The_Other_Thing will be called.
If the set of values that match the choice(s) of an earlier alternative
overlaps the corresponding set of a later alternative, then the first
set shall be a proper subset of the second (and the later alternative
-will not be executed if the earlier alternative "matches"). All possible
+will not be executed if the earlier alternative “matches”). All possible
values of the composite type shall be covered. The composite type of the
-selector shall be a nonlimited untagged undiscriminated record type, all
-of whose subcomponent subtypes are either static discrete subtypes or
-record types that meet the same restrictions. Support for arrays is
-planned, but not yet implemented.
+selector shall be a nonlimited untagged (but possibly discriminated)
+record type, all of whose subcomponent subtypes are either static discrete
+subtypes or record types that meet the same restrictions. Support for arrays
+is planned, but not yet implemented.
In addition, pattern bindings are supported. This is a mechanism
for binding a name to a component of a matching value for use within
an alternative of a case statement. For a component association
that occurs within a case choice, the expression may be followed by
-"is <identifier>". In the special case of a "box" component association,
+“is <identifier>”. In the special case of a “box” component association,
the identifier may instead be provided within the box. Either of these
indicates that the given identifer denotes (a constant view of) the matching
subcomponent of the case selector.
@@ -3750,7 +3750,7 @@ Fixed lower bounds for array types and subtypes
Unconstrained array types and subtypes can be specified with a lower bound
that is fixed to a certain value, by writing an index range that uses the
-syntax "<lower-bound-expression> .. <>". This guarantees that all objects
+syntax “<lower-bound-expression> .. <>”. This guarantees that all objects
of the type or subtype will have the specified lower bound.
For example, a matrix type with fixed lower bounds of zero for each
@@ -3780,7 +3780,7 @@ subtype String_1 is String (1 .. <>);
@end quotation
If a string slice is passed to a formal of subtype String_1 in a call to
-a subprogram S, the slice's bounds will "slide" so that the lower bound
+a subprogram S, the slice’s bounds will “slide” so that the lower bound
is 1. Within S, the lower bound of the formal is known to be 1, so, unlike
a normal unconstrained String formal, there is no need to worry about
accounting for other possible lower-bound values. Sliding of bounds also
@@ -3790,8 +3790,26 @@ conversions.
Use of this feature increases safety by simplifying code, and can also
improve the efficiency of indexing operations, since the compiler statically
-knows the lower bound of unconstrained array formals when the formal's
+knows the lower bound of unconstrained array formals when the formal’s
subtype has index ranges with static fixed lower bounds.
+
+@item
+Prefixed-view notation for calls to primitive subprograms of untagged types
+
+Since Ada 2005, calls to primitive subprograms of a tagged type that
+have a “prefixed view” (see RM 4.1.3(9.2)) have been allowed to be
+written using the form of a selected_component, with the first actual
+parameter given as the prefix and the name of the subprogram as a
+selector. This prefixed-view notation for calls is extended so as to
+also allow such syntax for calls to primitive subprograms of untagged
+types. The primitives of an untagged type T that have a prefixed view
+are those where the first formal parameter of the subprogram either
+is of type T or is an anonymous access parameter whose designated type
+is T. For a type that has a component that happens to have the same
+simple name as one of the type’s primitive subprograms, where the
+component is visible at the point of a selected_component using that
+name, preference is given to the component in a selected_component
+(as is currently the case for tagged types with such component names).
@end itemize
@node Pragma Extensions_Visible,Pragma External,Pragma Extensions_Allowed,Implementation Defined Pragmas
@@ -4022,7 +4040,7 @@ No other value of digits is permitted.
@end itemize
@node Pragma Ghost,Pragma Global,Pragma Float_Representation,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-ghost}@anchor{6e}@anchor{gnat_rm/implementation_defined_pragmas id14}@anchor{6f}
+@anchor{gnat_rm/implementation_defined_pragmas id14}@anchor{6e}@anchor{gnat_rm/implementation_defined_pragmas pragma-ghost}@anchor{6f}
@section Pragma Ghost
@@ -4036,7 +4054,7 @@ For the semantics of this pragma, see the entry for aspect @code{Ghost} in the S
2014 Reference Manual, section 6.9.
@node Pragma Global,Pragma Ident,Pragma Ghost,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-global}@anchor{70}@anchor{gnat_rm/implementation_defined_pragmas id15}@anchor{71}
+@anchor{gnat_rm/implementation_defined_pragmas id15}@anchor{70}@anchor{gnat_rm/implementation_defined_pragmas pragma-global}@anchor{71}
@section Pragma Global
@@ -4165,7 +4183,7 @@ By_Entry guarantees that the action of requeueing will proceed from an entry to
another entry. Implementation kind By_Protected_Procedure transforms the
requeue into a dispatching call, thus eliminating the chance of blocking. Kind
By_Any shares the behavior of By_Entry and By_Protected_Procedure depending on
-the target's overriding subprogram kind.
+the target’s overriding subprogram kind.
@node Pragma Implicit_Packing,Pragma Import_Function,Pragma Implemented,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-implicit-packing}@anchor{76}
@@ -4544,14 +4562,14 @@ Initialization with low values.
Initialization with a specific bit pattern.
@end itemize
-See the GNAT User's Guide for binder options for specifying these cases.
+See the GNAT User’s Guide for binder options for specifying these cases.
The bind-time approach is intended to provide fast turnaround for testing
with different values, without having to recompile the program.
@item
At execution time, the programmer can specify the invalid values using an
-environment variable. See the GNAT User's Guide for details.
+environment variable. See the GNAT User’s Guide for details.
The execution-time approach is intended to provide fast turnaround for
testing with different values, without having to recompile and rebind the
@@ -4561,7 +4579,7 @@ program.
Note that pragma @code{Initialize_Scalars} is particularly useful in conjunction
with the enhanced validity checking that is now provided in GNAT, which checks
for invalid values under more conditions. Using this feature (see description
-of the @emph{-gnatV} flag in the GNAT User's Guide) in conjunction with pragma
+of the @emph{-gnatV} flag in the GNAT User’s Guide) in conjunction with pragma
@code{Initialize_Scalars} provides a powerful new tool to assist in the detection
of problems caused by uninitialized variables.
@@ -4569,10 +4587,10 @@ Note: the use of @code{Initialize_Scalars} has a fairly extensive effect on the
generated code. This may cause your code to be substantially larger. It may
also cause an increase in the amount of stack required, so it is probably a
good idea to turn on stack checking (see description of stack checking in the
-GNAT User's Guide) when using this pragma.
+GNAT User’s Guide) when using this pragma.
@node Pragma Initializes,Pragma Inline_Always,Pragma Initialize_Scalars,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-initializes}@anchor{80}@anchor{gnat_rm/implementation_defined_pragmas id17}@anchor{81}
+@anchor{gnat_rm/implementation_defined_pragmas id17}@anchor{80}@anchor{gnat_rm/implementation_defined_pragmas pragma-initializes}@anchor{81}
@section Pragma Initializes
@@ -4778,7 +4796,7 @@ operating system documentation, or the value of the array @code{Reserved}
declared in the spec of package @code{System.OS_Interface}.
Overriding the default state of signals used by the Ada runtime may interfere
-with an application's runtime behavior in the cases of the synchronous signals,
+with an application’s runtime behavior in the cases of the synchronous signals,
and in the case of the signal used to implement the @code{abort} statement.
@node Pragma Invariant,Pragma Keep_Names,Pragma Interrupt_State,Implementation Defined Pragmas
@@ -4813,7 +4831,7 @@ is violated. If no Message parameter is provided, a default message that
identifies the line on which the pragma appears is used.
It is permissible to have multiple Invariants for the same type entity, in
-which case they are and'ed together. It is permissible to use this pragma
+which case they are and’ed together. It is permissible to use this pragma
in Ada 2012 mode, but you cannot have both an invariant aspect and an
invariant pragma for the same entity.
@@ -4897,13 +4915,13 @@ are recognized, and license information is derived from them as follows.
A GNAT license header starts with a line containing 78 hyphens. The following
comment text is searched for the appearance of any of the following strings.
-If the string 'GNU General Public License' is found, then the unit is assumed
-to have GPL license, unless the string 'As a special exception' follows, in
+If the string ‘GNU General Public License’ is found, then the unit is assumed
+to have GPL license, unless the string ‘As a special exception’ follows, in
which case the license is assumed to be modified GPL.
If one of the strings
-'This specification is adapted from the Ada Semantic Interface' or
-'This specification is derived from the Ada Reference Manual' is found
+‘This specification is adapted from the Ada Semantic Interface’ or
+‘This specification is derived from the Ada Reference Manual’ is found
then the unit is assumed to be unrestricted.
These default actions means that a program with a restricted license pragma
@@ -5071,7 +5089,7 @@ declared at the library level. This pragma specifies the name of the
linker section for the given entity. It is equivalent to
@code{__attribute__((section))} in GNU C and causes @code{LOCAL_NAME} to
be placed in the @code{static_string_EXPRESSION} section of the
-executable (assuming the linker doesn't rename the section).
+executable (assuming the linker doesn’t rename the section).
GNAT also provides an implementation defined aspect of the same name.
In the case of specifying this aspect for a type, the effect is to
@@ -5199,7 +5217,7 @@ except that in an @code{Assertion_Policy} pragma, the identifier
of statements of a loop body, or nested inside block statements that
appear in the sequence of statements of a loop body.
The intention is that it be used to
-represent a "loop invariant" assertion, i.e. something that is true each
+represent a “loop invariant” assertion, i.e. something that is true each
time through the loop, and which can be used to show that the loop is
achieving its purpose.
@@ -5339,7 +5357,7 @@ Machine-dependent attributes can be specified for types and/or
declarations. This pragma is semantically equivalent to
@code{__attribute__((@emph{attribute_name}))} (if @code{info} is not
specified) or @code{__attribute__((@emph{attribute_name(info})))}
-or @code{__attribute__((@emph{attribute_name(info,...})))} in GNU C,
+or @code{__attribute__((@emph{attribute_name(info,…})))} in GNU C,
where @emph{attribute_name} is recognized by the compiler middle-end
or the @code{TARGET_ATTRIBUTE_TABLE} machine specific macro. Note
that a string literal for the optional parameter @code{info} or the
@@ -5428,7 +5446,7 @@ dummy body with a No_Body pragma ensures that there is no interference from
earlier versions of the package body.
@node Pragma No_Caching,Pragma No_Component_Reordering,Pragma No_Body,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-caching}@anchor{9e}@anchor{gnat_rm/implementation_defined_pragmas id23}@anchor{9f}
+@anchor{gnat_rm/implementation_defined_pragmas id23}@anchor{9e}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-caching}@anchor{9f}
@section Pragma No_Caching
@@ -5475,7 +5493,7 @@ This is a program unit pragma (there is also an equivalent aspect of the
same name) that establishes the restriction @code{No_Elaboration_Code} for
the current unit and any extended main source units (body and subunits).
It also has the effect of enforcing a transitive application of this
-aspect, so that if any unit is implicitly or explicitly with'ed by the
+aspect, so that if any unit is implicitly or explicitly with’ed by the
current unit, it must also have the No_Elaboration_Code_All aspect set.
It may be applied to package or subprogram specs or their generic versions.
@@ -5574,12 +5592,12 @@ arguments is a configuration pragma which applies to all access types
declared in units to which the pragma applies. For a detailed
description of the strict aliasing optimization, and the situations
in which it must be suppressed, see the section on Optimization and Strict Aliasing
-in the @cite{GNAT User's Guide}.
+in the @cite{GNAT User’s Guide}.
This pragma currently has no effects on access to unconstrained array types.
@node Pragma No_Tagged_Streams,Pragma Normalize_Scalars,Pragma No_Strict_Aliasing,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{a8}@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{a9}
+@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{a8}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{a9}
@section Pragma No_Tagged_Streams
@@ -5639,14 +5657,14 @@ are as follows:
@item @emph{Standard.Character}
Objects whose root type is Standard.Character are initialized to
-Character'Last unless the subtype range excludes NUL (in which case
+Character’Last unless the subtype range excludes NUL (in which case
NUL is used). This choice will always generate an invalid value if
one exists.
@item @emph{Standard.Wide_Character}
Objects whose root type is Standard.Wide_Character are initialized to
-Wide_Character'Last unless the subtype range excludes NUL (in which case
+Wide_Character’Last unless the subtype range excludes NUL (in which case
NUL is used). This choice will always generate an invalid value if
one exists.
@@ -5700,7 +5718,7 @@ will always generate an invalid value if one exists.
@end table
@node Pragma Obsolescent,Pragma Optimize_Alignment,Pragma Normalize_Scalars,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{ab}@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{ac}
+@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{ab}@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{ac}
@section Pragma Obsolescent
@@ -5971,7 +5989,7 @@ template can be instantiated for both cases), so we never generate warnings
for the case of generic enumerated types.
For additional information please refer to the description of the
-@emph{-gnatw.u} switch in the GNAT User's Guide.
+@emph{-gnatw.u} switch in the GNAT User’s Guide.
@node Pragma Overflow_Mode,Pragma Overriding_Renamings,Pragma Ordered,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-overflow-mode}@anchor{af}
@@ -5990,8 +6008,8 @@ MODE ::= STRICT | MINIMIZED | ELIMINATED
This pragma sets the current overflow mode to the given setting. For details
of the meaning of these modes, please refer to the
-'Overflow Check Handling in GNAT' appendix in the
-GNAT User's Guide. If only the @code{General} parameter is present,
+‘Overflow Check Handling in GNAT’ appendix in the
+GNAT User’s Guide. If only the @code{General} parameter is present,
the given mode applies to all expressions. If both parameters are present,
the @code{General} mode applies to expressions outside assertions, and
the @code{Eliminated} mode applies to expressions within assertions.
@@ -6102,7 +6120,7 @@ optimized. GNAT does not attempt to optimize any tasks in this manner
(since protected objects are available in place of passive tasks).
For more information on the subject of passive tasks, see the section
-'Passive Task Optimization' in the GNAT Users Guide.
+‘Passive Task Optimization’ in the GNAT Users Guide.
@node Pragma Persistent_BSS,Pragma Post,Pragma Passive,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas id29}@anchor{b5}@anchor{gnat_rm/implementation_defined_pragmas pragma-persistent-bss}@anchor{b6}
@@ -6186,7 +6204,7 @@ implicit returns at the end of procedure bodies and associated
exception handlers).
In addition, the boolean expression which is the condition which
-must be true may contain references to function'Result in the case
+must be true may contain references to function’Result in the case
of a function to refer to the returned value.
@code{Postcondition} pragmas may appear either immediately following the
@@ -6253,7 +6271,7 @@ If a postcondition fails, then the exception
a message argument was supplied, then the given string
will be used as the exception message. If no message
argument was supplied, then the default message has
-the form "Postcondition failed at file_name:line". The
+the form “Postcondition failed at file_name:line”. The
exception is raised in the context of the subprogram
body, so it is possible to catch postcondition failures
within the subprogram body itself.
@@ -6393,11 +6411,11 @@ pragma Rename_Pragma (
Renamed => Inline_Always);
@end example
-Then GNAT will treat "pragma Inline_Only ..." as if you had written
-"pragma Inline_Always ...".
+Then GNAT will treat “pragma Inline_Only …” as if you had written
+“pragma Inline_Always …”.
Pragma Inline_Only will not necessarily mean the same thing as the other Ada
-compiler; it's up to you to make sure the semantics are close enough.
+compiler; it’s up to you to make sure the semantics are close enough.
@node Pragma Pre,Pragma Precondition,Pragma Rename_Pragma,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-pre}@anchor{bb}
@@ -6445,7 +6463,7 @@ pragma Precondition (
The @code{Precondition} pragma is similar to @code{Postcondition}
except that the corresponding checks take place immediately upon
entry to the subprogram, and if a precondition fails, the exception
-is raised in the context of the caller, and the attribute 'Result
+is raised in the context of the caller, and the attribute ‘Result
cannot be used within the precondition expression.
Otherwise, the placement and visibility rules are identical to those
@@ -6484,7 +6502,7 @@ Ada 2012, and has been retained in its original form for
compatibility purposes.
@node Pragma Predicate,Pragma Predicate_Failure,Pragma Precondition,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{bd}@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{be}
+@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{bd}@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{be}
@section Pragma Predicate
@@ -6529,7 +6547,7 @@ the program and thus do not have a neutral effect if ignored.
The motivation behind providing pragmas equivalent to
corresponding aspects is to allow a program to be written
using the pragmas, and then compiled with a compiler that
-will ignore the pragmas. That doesn't work in the case of
+will ignore the pragmas. That doesn’t work in the case of
static and dynamic predicates, since if the corresponding
pragmas are ignored, then the behavior of the program is
fundamentally changed (for example a membership test
@@ -6806,7 +6824,7 @@ packages:
@end itemize
This set of configuration pragmas and restrictions correspond to the
-definition of the 'Ravenscar Profile' for limited tasking, devised and
+definition of the ‘Ravenscar Profile’ for limited tasking, devised and
published by the @cite{International Real-Time Ada Workshop@comma{} 1997}.
A description is also available at
@indicateurl{http://www-users.cs.york.ac.uk/~burns/ravenscar.ps}.
@@ -6849,7 +6867,7 @@ The @code{Max_Protected_Entries}, @code{Max_Entry_Queue_Length}, and
Details on the rationale for @code{Jorvik} and implications for use may be
found in @cite{A New Ravenscar-Based Profile} by P. Rogers, J. Ruiz,
-T. Gingold and P. Bernardi, in @cite{Reliable Software Technologies -- Ada Europe 2017}, Springer-Verlag Lecture Notes in Computer Science,
+T. Gingold and P. Bernardi, in @cite{Reliable Software Technologies – Ada Europe 2017}, Springer-Verlag Lecture Notes in Computer Science,
Number 10300.
@item
@@ -6993,7 +7011,7 @@ either an unsigned or signed type. It has the effect of providing the
five shift operators (Shift_Left, Shift_Right, Shift_Right_Arithmetic,
Rotate_Left and Rotate_Right) for the given type. It is similar to
including the function declarations for these five operators, together
-with the pragma Import (Intrinsic, ...) statements.
+with the pragma Import (Intrinsic, …) statements.
@node Pragma Psect_Object,Pragma Pure_Function,Pragma Provide_Shift_Operators,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{c8}
@@ -7016,7 +7034,7 @@ EXTERNAL_SYMBOL ::=
This pragma is identical in effect to pragma @code{Common_Object}.
@node Pragma Pure_Function,Pragma Rational,Pragma Psect_Object,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{c9}@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{ca}
+@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{c9}@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{ca}
@section Pragma Pure_Function
@@ -7116,7 +7134,7 @@ pragma Profile (Ravenscar);
which is the preferred method of setting the @code{Ravenscar} profile.
@node Pragma Refined_Depends,Pragma Refined_Global,Pragma Ravenscar,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{cd}@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{ce}
+@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{cd}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{ce}
@section Pragma Refined_Depends
@@ -7149,7 +7167,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Depends
the SPARK 2014 Reference Manual, section 6.1.5.
@node Pragma Refined_Global,Pragma Refined_Post,Pragma Refined_Depends,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{cf}@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{d0}
+@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{cf}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d0}
@section Pragma Refined_Global
@@ -7174,7 +7192,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Global}
the SPARK 2014 Reference Manual, section 6.1.4.
@node Pragma Refined_Post,Pragma Refined_State,Pragma Refined_Global,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d1}@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d2}
+@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d1}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d2}
@section Pragma Refined_Post
@@ -7188,7 +7206,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Post} i
the SPARK 2014 Reference Manual, section 7.2.7.
@node Pragma Refined_State,Pragma Relative_Deadline,Pragma Refined_Post,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d3}@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d4}
+@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d3}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d4}
@section Pragma Refined_State
@@ -7445,7 +7463,7 @@ an @code{integer_EXPRESSION} of bytes is assigned from the primary stack instead
For most targets, the pragma does not apply as the secondary stack grows on
demand: allocated as a chain of blocks in the heap. The default size of these
blocks can be modified via the @code{-D} binder option as described in
-@cite{GNAT User's Guide}.
+@cite{GNAT User’s Guide}.
Note that no check is made to see if the secondary stack can fit inside the
primary stack.
@@ -7513,7 +7531,7 @@ This pragma is provided for compatibility with other Ada implementations. It
is recognized but ignored by all current versions of GNAT.
@node Pragma Simple_Storage_Pool_Type,Pragma Source_File_Name,Pragma Short_Descriptors,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e2}@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e3}
+@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e2}@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e3}
@section Pragma Simple_Storage_Pool_Type
@@ -7528,7 +7546,7 @@ Syntax:
pragma Simple_Storage_Pool_Type (type_LOCAL_NAME);
@end example
-A type can be established as a 'simple storage pool type' by applying
+A type can be established as a ‘simple storage pool type’ by applying
the representation pragma @code{Simple_Storage_Pool_Type} to the type.
A type named in the pragma must be a library-level immutably limited record
type or limited tagged type declared immediately within a package declaration.
@@ -7581,7 +7599,7 @@ See attribute @ref{e4,,Simple_Storage_Pool}
for further details.
@node Pragma Source_File_Name,Pragma Source_File_Name_Project,Pragma Simple_Storage_Pool_Type,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{e5}@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{e6}
+@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{e5}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{e6}
@section Pragma Source_File_Name
@@ -7677,16 +7695,16 @@ Source_File_Name cannot appear after a @ref{e7,,Pragma Source_File_Name_Project}
For more details on the use of the @code{Source_File_Name} pragma, see the
sections on @cite{Using Other File Names} and @cite{Alternative File Naming Schemes}
-in the @cite{GNAT User's Guide}.
+in the @cite{GNAT User’s Guide}.
@node Pragma Source_File_Name_Project,Pragma Source_Reference,Pragma Source_File_Name,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{e7}@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{e8}
+@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{e8}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{e7}
@section Pragma Source_File_Name_Project
This pragma has the same syntax and semantics as pragma Source_File_Name.
It is only allowed as a stand-alone configuration pragma.
-It cannot appear after a @ref{e5,,Pragma Source_File_Name}, and
+It cannot appear after a @ref{e6,,Pragma Source_File_Name}, and
most importantly, once pragma Source_File_Name_Project appears,
no further Source_File_Name pragmas are allowed.
@@ -7722,7 +7740,7 @@ string expression other than a string literal. This is because its value
is needed for error messages issued by all phases of the compiler.
@node Pragma SPARK_Mode,Pragma Static_Elaboration_Desired,Pragma Source_Reference,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{eb}
+@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{eb}
@section Pragma SPARK_Mode
@@ -7769,7 +7787,7 @@ Normally a subprogram or package spec/body inherits the current mode
that is active at the point it is declared. But this can be overridden
by pragma within the spec or body as above.
-The basic consistency rule is that you can't turn SPARK_Mode back
+The basic consistency rule is that you can’t turn SPARK_Mode back
@code{On}, once you have explicitly (with a pragma) turned if
@code{Off}. So the following rules apply:
@@ -7896,7 +7914,7 @@ The effect is that if the value of an unbounded string is written to a stream,
then the representation of the item in the stream is in the same format that
would be used for @code{Standard.String'Output}, and this same representation
is expected when a value of this type is read from the stream. Note that the
-value written always includes the bounds, even for Unbounded_String'Write,
+value written always includes the bounds, even for Unbounded_String’Write,
since Unbounded_String is not an array type.
Note that the @code{Stream_Convert} pragma is not effective in the case of
@@ -7947,7 +7965,7 @@ gcc -c -gnatyl ...
The form @code{ALL_CHECKS} activates all standard checks (its use is equivalent
to the use of the @code{gnaty} switch with no options.
-See the @cite{GNAT User's Guide} for details.)
+See the @cite{GNAT User’s Guide} for details.)
Note: the behavior is slightly different in GNAT mode (@code{-gnatg} used).
In this case, @code{ALL_CHECKS} implies the standard set of GNAT mode style check
@@ -8058,7 +8076,7 @@ checks, but does not require the compiler to omit checks. The compiler
will generate checks if they are essentially free, even when they are
suppressed. In particular, if the compiler can prove that a certain
check will necessarily fail, it will generate code to do an
-unconditional 'raise', even if checks are suppressed. The compiler
+unconditional ‘raise’, even if checks are suppressed. The compiler
warns in this case.
Of course, run-time checks are omitted whenever the compiler can prove
@@ -8084,7 +8102,7 @@ The use of the standard Ada pragma @code{Suppress (All_Checks)}
as a normal configuration pragma is the preferred usage in GNAT.
@node Pragma Suppress_Debug_Info,Pragma Suppress_Exception_Locations,Pragma Suppress_All,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f2}@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f3}
+@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f2}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f3}
@section Pragma Suppress_Debug_Info
@@ -8243,7 +8261,7 @@ created, depending on the target. This pragma can appear anywhere a
type.
@node Pragma Test_Case,Pragma Thread_Local_Storage,Pragma Task_Storage,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{f9}@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{fa}
+@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{f9}@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{fa}
@section Pragma Test_Case
@@ -8299,7 +8317,7 @@ postcondition. Mode @code{Robustness} indicates that the precondition and
postcondition of the subprogram should be ignored for this test case.
@node Pragma Thread_Local_Storage,Pragma Time_Slice,Pragma Test_Case,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{fb}@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{fc}
+@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{fb}@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{fc}
@section Pragma Thread_Local_Storage
@@ -8317,7 +8335,7 @@ pragma Thread_Local_Storage ([Entity =>] LOCAL_NAME);
This pragma specifies that the specified entity, which must be
a variable declared in a library-level package, is to be marked as
-"Thread Local Storage" (@code{TLS}). On systems supporting this (which
+“Thread Local Storage” (@code{TLS}). On systems supporting this (which
include Windows, Solaris, GNU/Linux, and VxWorks 6), this causes each
thread (and hence each Ada task) to see a distinct copy of the variable.
@@ -8521,7 +8539,7 @@ The abort only happens if code is being generated. Thus you can use
specs of unimplemented packages in syntax or semantic checking mode.
@node Pragma Universal_Aliasing,Pragma Unmodified,Pragma Unimplemented_Unit,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{105}@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{106}
+@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{105}@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{106}
@section Pragma Universal_Aliasing
@@ -8537,10 +8555,10 @@ optimization for the given type. In other words, the effect is as though
access types designating this type were subject to pragma No_Strict_Aliasing.
For a detailed description of the strict aliasing optimization, and the
situations in which it must be suppressed, see the section on
-@code{Optimization and Strict Aliasing} in the @cite{GNAT User's Guide}.
+@code{Optimization and Strict Aliasing} in the @cite{GNAT User’s Guide}.
@node Pragma Unmodified,Pragma Unreferenced,Pragma Universal_Aliasing,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{107}@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{108}
+@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{107}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{108}
@section Pragma Unmodified
@@ -8574,7 +8592,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such
variables, though it is harmless to do so.
@node Pragma Unreferenced,Pragma Unreferenced_Objects,Pragma Unmodified,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{109}@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{10a}
+@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{109}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{10a}
@section Pragma Unreferenced
@@ -8618,7 +8636,7 @@ Note that if a warning is desired for all calls to a given subprogram,
regardless of whether they occur in the same unit as the subprogram
declaration, then this pragma should not be used (calls from another
unit would not be flagged); pragma Obsolescent can be used instead
-for this purpose, see @ref{ab,,Pragma Obsolescent}.
+for this purpose, see @ref{ac,,Pragma Obsolescent}.
The second form of pragma @code{Unreferenced} is used within a context
clause. In this case the arguments must be unit names of units previously
@@ -8634,7 +8652,7 @@ Thus it is never necessary to use @code{pragma Unreferenced} for such
variables, though it is harmless to do so.
@node Pragma Unreferenced_Objects,Pragma Unreserve_All_Interrupts,Pragma Unreferenced,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{10b}@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{10c}
+@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{10b}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{10c}
@section Pragma Unreferenced_Objects
@@ -8747,15 +8765,15 @@ pragma Use_VADS_Size;
@end example
This is a configuration pragma. In a unit to which it applies, any use
-of the 'Size attribute is automatically interpreted as a use of the
-'VADS_Size attribute. Note that this may result in incorrect semantic
+of the ‘Size attribute is automatically interpreted as a use of the
+‘VADS_Size attribute. Note that this may result in incorrect semantic
processing of valid Ada 95 or Ada 2005 programs. This is intended to aid in
the handling of existing code which depends on the interpretation of Size
as implemented in the VADS compiler. See description of the VADS_Size
attribute for further details.
@node Pragma Unused,Pragma Validity_Checks,Pragma Use_VADS_Size,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{111}
+@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{111}
@section Pragma Unused
@@ -8812,7 +8830,7 @@ activated. The validity checks are first set to include only the default
reference manual settings, and then a string of letters in the string
specifies the exact set of options required. The form of this string
is exactly as described for the @emph{-gnatVx} compiler switch (see the
-GNAT User's Guide for details). For example the following two
+GNAT User’s Guide for details). For example the following two
methods can be used to enable validity checking for mode @code{in} and
@code{in out} subprogram parameters:
@@ -8845,7 +8863,7 @@ A := C; -- C will be validity checked
@end example
@node Pragma Volatile,Pragma Volatile_Full_Access,Pragma Validity_Checks,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{113}@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{114}
+@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{113}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{114}
@section Pragma Volatile
@@ -8920,7 +8938,7 @@ as an error. This gives more precise control than -gnatwe,
which treats warnings as errors.
This pragma can apply to regular warnings (messages enabled by -gnatw)
-and to style warnings (messages that start with "(style)",
+and to style warnings (messages that start with “(style)”,
enabled by -gnaty).
The pattern may contain asterisks, which match zero or more characters
@@ -8989,8 +9007,8 @@ Note that this pragma does not affect the set of warnings issued in
any way, it merely changes the effect of a matching warning if one
is produced as a result of other warnings options. As shown in this
example, if the pragma results in a warning being treated as an error,
-the tag is changed from "warning:" to "error:" and the string
-"[warning-as-error]" is appended to the end of the message.
+the tag is changed from “warning:” to “error:” and the string
+“[warning-as-error]” is appended to the end of the message.
@node Pragma Warnings,Pragma Weak_External,Pragma Warning_As_Error,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11b}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{11a}
@@ -9059,7 +9077,7 @@ line switch controlling warnings. For a brief summary, use the gnatmake
command with no arguments, which will generate usage information containing
the list of warnings switches supported. For
full details see the section on @code{Warning Message Control} in the
-@cite{GNAT User's Guide}.
+@cite{GNAT User’s Guide}.
This form can also be used as a configuration pragma.
The warnings controlled by the @code{-gnatw} switch are generated by the
@@ -9081,7 +9099,7 @@ also be used as a configuration pragma.
The fourth form, with an @code{On|Off} parameter and a string, is used to
control individual messages, based on their text. The string argument
is a pattern that is used to match against the text of individual
-warning messages (not including the initial "warning: " tag).
+warning messages (not including the initial “warning: ” tag).
The pattern may contain asterisks, which match zero or more characters in
the message. For example, you can use
@@ -9218,7 +9236,7 @@ to appear within the same file.
However, note that the pragma cannot immediately precede the relevant
wide character, because then the previous encoding will still be in
-effect, causing "illegal character" errors.
+effect, causing “illegal character” errors.
The argument can be an identifier or a character literal. In the identifier
case, it is one of @code{HEX}, @code{UPPER}, @code{SHIFT_JIS},
@@ -9231,7 +9249,7 @@ encoding within that file, and does not affect withed units, specs,
or subunits.
@node Implementation Defined Aspects,Implementation Defined Attributes,Implementation Defined Pragmas,Top
-@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{11e}@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{11f}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{120}
+@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{11e}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{11f}@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{120}
@chapter Implementation Defined Aspects
@@ -9307,7 +9325,7 @@ or attribute definition clause.
* Aspect Initializes::
* Aspect Inline_Always::
* Aspect Invariant::
-* Aspect Invariant'Class::
+* Aspect Invariant’Class::
* Aspect Iterable::
* Aspect Linker_Section::
* Aspect Lock_Free::
@@ -9357,7 +9375,7 @@ or attribute definition clause.
@geindex Abstract_State
-This aspect is equivalent to @ref{1c,,pragma Abstract_State}.
+This aspect is equivalent to @ref{1d,,pragma Abstract_State}.
@node Aspect Annotate,Aspect Async_Readers,Aspect Abstract_State,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{122}
@@ -9368,7 +9386,7 @@ This aspect is equivalent to @ref{1c,,pragma Abstract_State}.
There are three forms of this aspect (where ID is an identifier,
and ARG is a general expression),
-corresponding to @ref{26,,pragma Annotate}.
+corresponding to @ref{27,,pragma Annotate}.
@table @asis
@@ -9393,7 +9411,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);}
@geindex Async_Readers
-This boolean aspect is equivalent to @ref{2d,,pragma Async_Readers}.
+This boolean aspect is equivalent to @ref{2e,,pragma Async_Readers}.
@node Aspect Async_Writers,Aspect Constant_After_Elaboration,Aspect Async_Readers,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{124}
@@ -9431,7 +9449,7 @@ aggregate.
@geindex Depends
-This aspect is equivalent to @ref{53,,pragma Depends}.
+This aspect is equivalent to @ref{54,,pragma Depends}.
@node Aspect Default_Initial_Condition,Aspect Dimension,Aspect Depends,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{128}
@@ -9535,7 +9553,7 @@ Note that in the above type definition, we use the @code{at} symbol (@code{@@})
represent a theta character (avoiding the use of extended Latin-1
characters in this context).
-See section 'Performing Dimensionality Analysis in GNAT' in the GNAT Users
+See section ‘Performing Dimensionality Analysis in GNAT’ in the GNAT Users
Guide for detailed examples of use of the dimension system.
@node Aspect Disable_Controlled,Aspect Effective_Reads,Aspect Dimension_System,Implementation Defined Aspects
@@ -9594,7 +9612,7 @@ This boolean aspect is equivalent to @ref{6b,,pragma Favor_Top_Level}.
@geindex Ghost
-This aspect is equivalent to @ref{6e,,pragma Ghost}.
+This aspect is equivalent to @ref{6f,,pragma Ghost}.
@node Aspect Global,Aspect Initial_Condition,Aspect Ghost,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{131}
@@ -9603,7 +9621,7 @@ This aspect is equivalent to @ref{6e,,pragma Ghost}.
@geindex Global
-This aspect is equivalent to @ref{70,,pragma Global}.
+This aspect is equivalent to @ref{71,,pragma Global}.
@node Aspect Initial_Condition,Aspect Initializes,Aspect Global,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{132}
@@ -9621,7 +9639,7 @@ This aspect is equivalent to @ref{7e,,pragma Initial_Condition}.
@geindex Initializes
-This aspect is equivalent to @ref{80,,pragma Initializes}.
+This aspect is equivalent to @ref{81,,pragma Initializes}.
@node Aspect Inline_Always,Aspect Invariant,Aspect Initializes,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{134}
@@ -9632,7 +9650,7 @@ This aspect is equivalent to @ref{80,,pragma Initializes}.
This boolean aspect is equivalent to @ref{83,,pragma Inline_Always}.
-@node Aspect Invariant,Aspect Invariant'Class,Aspect Inline_Always,Implementation Defined Aspects
+@node Aspect Invariant,Aspect Invariant’Class,Aspect Inline_Always,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{135}
@section Aspect Invariant
@@ -9643,9 +9661,9 @@ This aspect is equivalent to @ref{8a,,pragma Invariant}. It is a
synonym for the language defined aspect @code{Type_Invariant} except
that it is separately controllable using pragma @code{Assertion_Policy}.
-@node Aspect Invariant'Class,Aspect Iterable,Aspect Invariant,Implementation Defined Aspects
+@node Aspect Invariant’Class,Aspect Iterable,Aspect Invariant,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{136}
-@section Aspect Invariant'Class
+@section Aspect Invariant’Class
@geindex Invariant'Class
@@ -9654,7 +9672,7 @@ This aspect is equivalent to @ref{101,,pragma Type_Invariant_Class}. It is a
synonym for the language defined aspect @code{Type_Invariant'Class} except
that it is separately controllable using pragma @code{Assertion_Policy}.
-@node Aspect Iterable,Aspect Linker_Section,Aspect Invariant'Class,Implementation Defined Aspects
+@node Aspect Iterable,Aspect Linker_Section,Aspect Invariant’Class,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{137}
@section Aspect Iterable
@@ -9768,7 +9786,7 @@ This aspect is equivalent to @ref{9c,,pragma Max_Queue_Length}.
@geindex No_Caching
-This boolean aspect is equivalent to @ref{9e,,pragma No_Caching}.
+This boolean aspect is equivalent to @ref{9f,,pragma No_Caching}.
@node Aspect No_Elaboration_Code_All,Aspect No_Inline,Aspect No_Caching,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{13c}
@@ -9796,7 +9814,7 @@ This boolean aspect is equivalent to @ref{a5,,pragma No_Inline}.
@geindex No_Tagged_Streams
-This aspect is equivalent to @ref{a8,,pragma No_Tagged_Streams} with an
+This aspect is equivalent to @ref{a9,,pragma No_Tagged_Streams} with an
argument specifying a root tagged type (thus this aspect can only be
applied to such a type).
@@ -9810,11 +9828,11 @@ applied to such a type).
Applies to a type. If True, requires that the type and any descendants
do not have any task parts. The rules for this aspect are the same as
for the language-defined No_Controlled_Parts aspect (see RM-H.4.1),
-replacing "controlled" with "task".
+replacing “controlled” with “task”.
If No_Task_Parts is True for a type T, then the compiler can optimize
away certain tasking-related code that would otherwise be needed
-for T'Class, because descendants of T might contain tasks.
+for T’Class, because descendants of T might contain tasks.
@node Aspect Object_Size,Aspect Obsolescent,Aspect No_Task_Parts,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{140}
@@ -9832,7 +9850,7 @@ This aspect is equivalent to @ref{141,,attribute Object_Size}.
@geindex Obsolsecent
-This aspect is equivalent to @ref{ab,,pragma Obsolescent}. Note that the
+This aspect is equivalent to @ref{ac,,pragma Obsolescent}. Note that the
evaluation of this aspect happens at the point of occurrence, it is not
delayed until the freeze point.
@@ -9861,7 +9879,7 @@ This boolean aspect is equivalent to @ref{b6,,pragma Persistent_BSS}.
@geindex Predicate
-This aspect is equivalent to @ref{bd,,pragma Predicate}. It is thus
+This aspect is equivalent to @ref{be,,pragma Predicate}. It is thus
similar to the language defined aspects @code{Dynamic_Predicate}
and @code{Static_Predicate} except that whether the resulting
predicate is static or dynamic is controlled by the form of the
@@ -9875,7 +9893,7 @@ expression. It is also separately controllable using pragma
@geindex Pure_Function
-This boolean aspect is equivalent to @ref{c9,,pragma Pure_Function}.
+This boolean aspect is equivalent to @ref{ca,,pragma Pure_Function}.
@node Aspect Refined_Depends,Aspect Refined_Global,Aspect Pure_Function,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{147}
@@ -9884,7 +9902,7 @@ This boolean aspect is equivalent to @ref{c9,,pragma Pure_Function}.
@geindex Refined_Depends
-This aspect is equivalent to @ref{cd,,pragma Refined_Depends}.
+This aspect is equivalent to @ref{ce,,pragma Refined_Depends}.
@node Aspect Refined_Global,Aspect Refined_Post,Aspect Refined_Depends,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{148}
@@ -9893,7 +9911,7 @@ This aspect is equivalent to @ref{cd,,pragma Refined_Depends}.
@geindex Refined_Global
-This aspect is equivalent to @ref{cf,,pragma Refined_Global}.
+This aspect is equivalent to @ref{d0,,pragma Refined_Global}.
@node Aspect Refined_Post,Aspect Refined_State,Aspect Refined_Global,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{149}
@@ -9902,7 +9920,7 @@ This aspect is equivalent to @ref{cf,,pragma Refined_Global}.
@geindex Refined_Post
-This aspect is equivalent to @ref{d1,,pragma Refined_Post}.
+This aspect is equivalent to @ref{d2,,pragma Refined_Post}.
@node Aspect Refined_State,Aspect Relaxed_Initialization,Aspect Refined_Post,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{14a}
@@ -9911,7 +9929,7 @@ This aspect is equivalent to @ref{d1,,pragma Refined_Post}.
@geindex Refined_State
-This aspect is equivalent to @ref{d3,,pragma Refined_State}.
+This aspect is equivalent to @ref{d4,,pragma Refined_State}.
@node Aspect Relaxed_Initialization,Aspect Remote_Access_Type,Aspect Refined_State,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-relaxed-initialization}@anchor{14b}
@@ -9976,7 +9994,7 @@ This aspect is equivalent to @ref{e4,,attribute Simple_Storage_Pool}.
@geindex Simple_Storage_Pool_Type
-This boolean aspect is equivalent to @ref{e2,,pragma Simple_Storage_Pool_Type}.
+This boolean aspect is equivalent to @ref{e3,,pragma Simple_Storage_Pool_Type}.
@node Aspect SPARK_Mode,Aspect Suppress_Debug_Info,Aspect Simple_Storage_Pool_Type,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{153}
@@ -9985,7 +10003,7 @@ This boolean aspect is equivalent to @ref{e2,,pragma Simple_Storage_Pool_Type}.
@geindex SPARK_Mode
-This aspect is equivalent to @ref{ea,,pragma SPARK_Mode} and
+This aspect is equivalent to @ref{eb,,pragma SPARK_Mode} and
may be specified for either or both of the specification and body
of a subprogram or package.
@@ -9996,7 +10014,7 @@ of a subprogram or package.
@geindex Suppress_Debug_Info
-This boolean aspect is equivalent to @ref{f2,,pragma Suppress_Debug_Info}.
+This boolean aspect is equivalent to @ref{f3,,pragma Suppress_Debug_Info}.
@node Aspect Suppress_Initialization,Aspect Test_Case,Aspect Suppress_Debug_Info,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{155}
@@ -10014,7 +10032,7 @@ This boolean aspect is equivalent to @ref{f6,,pragma Suppress_Initialization}.
@geindex Test_Case
-This aspect is equivalent to @ref{f9,,pragma Test_Case}.
+This aspect is equivalent to @ref{fa,,pragma Test_Case}.
@node Aspect Thread_Local_Storage,Aspect Universal_Aliasing,Aspect Test_Case,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{157}
@@ -10023,7 +10041,7 @@ This aspect is equivalent to @ref{f9,,pragma Test_Case}.
@geindex Thread_Local_Storage
-This boolean aspect is equivalent to @ref{fb,,pragma Thread_Local_Storage}.
+This boolean aspect is equivalent to @ref{fc,,pragma Thread_Local_Storage}.
@node Aspect Universal_Aliasing,Aspect Unmodified,Aspect Thread_Local_Storage,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{158}
@@ -10032,7 +10050,7 @@ This boolean aspect is equivalent to @ref{fb,,pragma Thread_Local_Storage}.
@geindex Universal_Aliasing
-This boolean aspect is equivalent to @ref{105,,pragma Universal_Aliasing}.
+This boolean aspect is equivalent to @ref{106,,pragma Universal_Aliasing}.
@node Aspect Unmodified,Aspect Unreferenced,Aspect Universal_Aliasing,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{159}
@@ -10041,7 +10059,7 @@ This boolean aspect is equivalent to @ref{105,,pragma Universal_Aliasing}.
@geindex Unmodified
-This boolean aspect is equivalent to @ref{107,,pragma Unmodified}.
+This boolean aspect is equivalent to @ref{108,,pragma Unmodified}.
@node Aspect Unreferenced,Aspect Unreferenced_Objects,Aspect Unmodified,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{15a}
@@ -10050,7 +10068,7 @@ This boolean aspect is equivalent to @ref{107,,pragma Unmodified}.
@geindex Unreferenced
-This boolean aspect is equivalent to @ref{109,,pragma Unreferenced}.
+This boolean aspect is equivalent to @ref{10a,,pragma Unreferenced}.
When using the @code{-gnat2022} switch, this aspect is also supported on formal
parameters, which is in particular the only form possible for expression
@@ -10063,7 +10081,7 @@ functions.
@geindex Unreferenced_Objects
-This boolean aspect is equivalent to @ref{10b,,pragma Unreferenced_Objects}.
+This boolean aspect is equivalent to @ref{10c,,pragma Unreferenced_Objects}.
@node Aspect Value_Size,Aspect Volatile_Full_Access,Aspect Unreferenced_Objects,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{15c}
@@ -10104,7 +10122,7 @@ where the first argument is @code{ON} or @code{OFF} and the second argument
is the entity.
@node Implementation Defined Attributes,Standard and Implementation Defined Restrictions,Implementation Defined Aspects,Top
-@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{161}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{162}
+@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{161}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{162}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}
@chapter Implementation Defined Attributes
@@ -10235,9 +10253,9 @@ intercept the abort exception).
@code{Standard'Address_Size} (@code{Standard} is the only allowed
prefix) is a static constant giving the number of bits in an
-@code{Address}. It is the same value as System.Address'Size,
+@code{Address}. It is the same value as System.Address’Size,
but has the advantage of being static, while a direct
-reference to System.Address'Size is nonstatic because Address
+reference to System.Address’Size is nonstatic because Address
is a private type.
@node Attribute Asm_Input,Attribute Asm_Output,Attribute Address_Size,Implementation Defined Attributes
@@ -10848,7 +10866,7 @@ standard input-output functions for fixed-point values.
@geindex Invalid_Value
-For every scalar type S, S'Invalid_Value returns an undefined value of the
+For every scalar type S, S’Invalid_Value returns an undefined value of the
type. If possible this value is an invalid representation for the type. The
value returned is identical to the value used to initialize an otherwise
uninitialized value of the type if pragma Initialize_Scalars is used,
@@ -11165,7 +11183,7 @@ bounds are allocated just before the first component,
whereas @code{X'Address} returns the address of the first
component.
-Here, we are interpreting 'storage pool' broadly to mean
+Here, we are interpreting ‘storage pool’ broadly to mean
@code{wherever the object is allocated}, which could be a
user-defined storage pool,
the global heap, on the stack, or in a static memory area.
@@ -11197,7 +11215,7 @@ same result as @code{Length} applied to the array itself.
This attribute allows compile time testing of restrictions that
are currently in effect. It is primarily intended for specializing
code in the run-time based on restrictions that are active (e.g.
-don't need to save fpt registers if restriction No_Floating_Point
+don’t need to save fpt registers if restriction No_Floating_Point
is known to be in effect), but can be used anywhere.
There are two forms:
@@ -11308,7 +11326,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{19c}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{14f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{14f}@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{19c}
@section Attribute Scalar_Storage_Order
@@ -11362,7 +11380,7 @@ defined by Ada RM 13.5.3(4). The default is @code{System.Default_Bit_Order}.
For a record type @code{T}, if @code{T'Scalar_Storage_Order} is
specified explicitly, it shall be equal to @code{T'Bit_Order}. Note:
this means that if a @code{Scalar_Storage_Order} attribute definition
-clause is not confirming, then the type's @code{Bit_Order} shall be
+clause is not confirming, then the type’s @code{Bit_Order} shall be
specified explicitly and set to the same value.
Derived types inherit an explicitly set scalar storage order from their parent
@@ -11423,6 +11441,46 @@ If a component of @code{T} is itself of a record or array type, the specfied
attribute definition clause must be provided for the component type as well
if desired.
+Representation changes that explicitly or implicitly toggle the scalar storage
+order are not supported and may result in erroneous execution of the program,
+except when performed by means of an instance of @code{Ada.Unchecked_Conversion}.
+
+In particular, overlays are not supported and a warning is given for them:
+
+@example
+type Rec_LE is record
+ I : Integer;
+end record;
+
+for Rec_LE use record
+ I at 0 range 0 .. 31;
+end record;
+
+for Rec_LE'Bit_Order use System.Low_Order_First;
+for Rec_LE'Scalar_Storage_Order use System.Low_Order_First;
+
+type Rec_BE is record
+ I : Integer;
+end record;
+
+for Rec_BE use record
+ I at 0 range 0 .. 31;
+end record;
+
+for Rec_BE'Bit_Order use System.High_Order_First;
+for Rec_BE'Scalar_Storage_Order use System.High_Order_First;
+
+R_LE : Rec_LE;
+
+R_BE : Rec_BE;
+for R_BE'Address use R_LE'Address;
+@end example
+
+@code{warning: overlay changes scalar storage order [enabled by default]}
+
+In most cases, such representation changes ought to be replaced by an
+instantiation of a function or procedure provided by @code{GNAT.Byte_Swapping}.
+
Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.
@@ -11456,7 +11514,7 @@ for Acc'Simple_Storage_Pool use My_Pool;
The name given in an attribute_definition_clause for the
@code{Simple_Storage_Pool} attribute shall denote a variable of
-a 'simple storage pool type' (see pragma @cite{Simple_Storage_Pool_Type}).
+a ‘simple storage pool type’ (see pragma @cite{Simple_Storage_Pool_Type}).
The use of this attribute is only allowed for a prefix denoting a type
for which it has been specified. The type of the attribute is the type
@@ -11555,7 +11613,7 @@ prefix) provides the same value as @code{System.Storage_Unit}.
The GNAT implementation of remote access-to-classwide types is
organized as described in AARM section E.4 (20.t): a value of an RACW type
(designating a remote object) is represented as a normal access
-value, pointing to a "stub" object which in turn contains the
+value, pointing to a “stub” object which in turn contains the
necessary information to contact the designated remote object. A
call on any dispatching operation of such a stub object does the
remote call, if necessary, using the information in the stub object
@@ -11597,7 +11655,7 @@ alignment request is larger than this value.
prefix) provides a static string value that identifies the target
for the current compilation. For GCC implementations, this is the
standard gcc target name without the terminating slash (for
-example, GNAT 5.0 on windows yields "i586-pc-mingw32msv").
+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}
@@ -11791,9 +11849,9 @@ For instance, if a function uses @code{Unrestricted_Access} to create
an access-to-unconstrained-array and returns that value to the caller,
the result will involve dangling pointers. In addition, it is only
valid to create pointers to unconstrained arrays using this attribute
-if the pointer has the normal default 'fat' representation where a
+if the pointer has the normal default ‘fat’ representation where a
pointer has two components, one points to the array and one points to
-the bounds. If a size clause is used to force 'thin' representation
+the bounds. If a size clause is used to force ‘thin’ representation
for a pointer to unconstrained where there is only space for a single
pointer, then the resulting pointer is not usable.
@@ -11909,7 +11967,7 @@ begin
end;
@end example
-In general this is a risky approach. It may appear to "work" but such uses of
+In general this is a risky approach. It may appear to “work” but such uses of
@code{Unrestricted_Access} are potentially non-portable, even from one version
of GNAT to another, so are best avoided if possible.
@@ -12061,7 +12119,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{1b1}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{15d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{15d}@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1b1}
@section Attribute Value_Size
@@ -12098,7 +12156,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{1b4}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1b4}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b5}@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9}
@chapter Standard and Implementation Defined Restrictions
@@ -12127,7 +12185,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{1b6}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b6}@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b7}
@section Partition-Wide Restrictions
@@ -12287,7 +12345,7 @@ defined by a discriminant of a subtype whose corresponding bound is static.
@geindex Max_Storage_At_Blocking
-[RM D.7] Specifies the maximum portion (in storage elements) of a task's
+[RM D.7] Specifies the maximum portion (in storage elements) of a task’s
Storage_Size that can be retained by a blocked task. A violation of this
restriction causes Storage_Error to be raised.
@@ -12407,7 +12465,7 @@ coextensions. See 3.10.2.
[GNAT] This restriction prohibits any instance of default initialization
of variables. The binder implements a consistency rule which prevents
-any unit compiled without the restriction from with'ing a unit with the
+any unit compiled without the restriction from with’ing a unit with the
restriction (this allows the generation of initialization procedures to
be skipped, since you can be sure that no call is ever generated to an
initialization procedure in a unit with the restriction active). If used
@@ -12723,7 +12781,7 @@ of composite objects and the Max/Min attributes.
@geindex trampoline
-[GNAT] This restriction prevents the compiler from building 'trampolines'.
+[GNAT] This restriction prevents the compiler from building ‘trampolines’.
This is a structure that is built on the stack and contains dynamic
code to be executed at run time. On some targets, a trampoline is
built for the following features: @code{Access},
@@ -12735,7 +12793,7 @@ protection) will cause trampolines to raise an exception.
Trampolines are also quite slow at run time.
On many targets, trampolines have been largely eliminated. Look at the
-version of system.ads for your target --- if it has
+version of system.ads for your target — if it has
Always_Compatible_Rep equal to False, then trampolines are largely
eliminated. In particular, a trampoline is built for the following
features: @code{Address} of a nested subprogram;
@@ -12836,7 +12894,7 @@ declared at the library level.
[GNAT] This partition-wide restriction forbids any explicit reference to
type Standard.Long_Long_Integer, and also forbids declaring range types whose
implicit base type is Long_Long_Integer, and modular types whose size exceeds
-Long_Integer'Size.
+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{1e4}
@@ -13202,7 +13260,7 @@ character literals,
implicitly defined comparison operators,
@item
-uses of the Standard."not" operator,
+uses of the Standard.”not” operator,
@item
short-circuit operator,
@@ -13256,7 +13314,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{203}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{204}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{203}@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{204}
@section Program Unit Level Restrictions
@@ -13332,7 +13390,7 @@ is not possible to document the precise conditions under which the
optimizer can figure this out.
Note that this the implementation of this restriction requires full
-code generation. If it is used in conjunction with "semantics only"
+code generation. If it is used in conjunction with “semantics only”
checking, then some cases of violations may be missed.
When this restriction is active, we are not requesting control-flow
@@ -13448,9 +13506,9 @@ of packages Ada, Interfaces, or System.
@geindex No_Implicit_Aliasing
[GNAT] This restriction, which is not required to be partition-wide consistent,
-requires an explicit aliased keyword for an object to which 'Access,
-'Unchecked_Access, or 'Address is applied, and forbids entirely the use of
-the 'Unrestricted_Access attribute for objects. Note: the reason that
+requires an explicit aliased keyword for an object to which ‘Access,
+‘Unchecked_Access, or ‘Address is applied, and forbids entirely the use of
+the ‘Unrestricted_Access attribute for objects. Note: the reason that
Unrestricted_Access is forbidden is that it would require the prefix
to be aliased, and in such cases, it can always be replaced by
the standard attribute Unchecked_Access which is preferable.
@@ -13530,7 +13588,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{214}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{215}
+@anchor{gnat_rm/implementation_advice doc}@anchor{214}@anchor{gnat_rm/implementation_advice id1}@anchor{215}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}
@chapter Implementation Advice
@@ -13539,7 +13597,7 @@ behavior of all Ada compilers, and the GNAT compiler conforms to
these requirements.
In addition, there are sections throughout the Ada Reference Manual headed
-by the phrase 'Implementation advice'. These sections are not normative,
+by the phrase ‘Implementation advice’. These sections are not normative,
i.e., they do not specify requirements that all compilers must
follow. Rather they provide advice on generally desirable behavior.
They are not requirements, because they describe behavior that cannot
@@ -13552,7 +13610,7 @@ RM section number and paragraph number and the subject of
the advice. The contents of each section consists of the RM text within
quotation marks,
followed by the GNAT interpretation of the advice. Most often, this simply says
-'followed', which means that GNAT follows the advice. However, in a
+‘followed’, which means that GNAT follows the advice. However, in a
number of cases, GNAT deliberately deviates from this advice, in which
case the text describes what GNAT does and why.
@@ -13570,7 +13628,7 @@ case the text describes what GNAT does and why.
* RM 3.5.5(8); Enumeration Values: RM 3 5 5 8 Enumeration Values.
* RM 3.5.7(17); Float Types: RM 3 5 7 17 Float Types.
* RM 3.6.2(11); Multidimensional Arrays: RM 3 6 2 11 Multidimensional Arrays.
-* RM 9.6(30-31); Duration'Small: RM 9 6 30-31 Duration'Small.
+* RM 9.6(30-31); Duration’Small: RM 9 6 30-31 Duration’Small.
* RM 10.2.1(12); Consistent Representation: RM 10 2 1 12 Consistent Representation.
* RM 11.4.1(19); Exception Information: RM 11 4 1 19 Exception Information.
* RM 11.5(28); Suppression of Checks: RM 11 5 28 Suppression of Checks.
@@ -13634,9 +13692,9 @@ case the text describes what GNAT does and why.
@quotation
-"If an implementation detects the use of an unsupported Specialized Needs
+“If an implementation detects the use of an unsupported Specialized Needs
Annex feature at run time, it should raise @code{Program_Error} if
-feasible."
+feasible.”
@end quotation
Not relevant. All specialized needs annex features are either supported,
@@ -13651,9 +13709,9 @@ or diagnosed at compile time.
@quotation
-"If an implementation wishes to provide implementation-defined
+“If an implementation wishes to provide implementation-defined
extensions to the functionality of a language-defined library unit, it
-should normally do so by adding children to the library unit."
+should normally do so by adding children to the library unit.”
@end quotation
Followed.
@@ -13667,8 +13725,8 @@ Followed.
@quotation
-"If an implementation detects a bounded error or erroneous
-execution, it should raise @code{Program_Error}."
+“If an implementation detects a bounded error or erroneous
+execution, it should raise @code{Program_Error}.”
@end quotation
Followed in all cases in which the implementation detects a bounded
@@ -13684,10 +13742,10 @@ runtime.
@quotation
-"Normally, implementation-defined pragmas should have no semantic effect
+“Normally, implementation-defined pragmas should have no semantic effect
for error-free programs; that is, if the implementation-defined pragmas
are removed from a working program, the program should still be legal,
-and should still have the same semantics."
+and should still have the same semantics.”
@end quotation
The following implementation defined pragmas are exceptions to this
@@ -13797,7 +13855,7 @@ that this advice not be followed. For details see
@quotation
-"Normally, an implementation should not define pragmas that can
+“Normally, an implementation should not define pragmas that can
make an illegal program legal, except as follows:
@@ -13808,7 +13866,7 @@ A pragma used to complete a declaration, such as a pragma @code{Import};
@item
A pragma used to configure the environment by adding, removing, or
-replacing @code{library_items}."
+replacing @code{library_items}.”
@end itemize
@end quotation
@@ -13825,16 +13883,16 @@ See @ref{21a,,RM 2.8(16); Pragmas}.
@quotation
-"If an implementation supports a mode with alternative interpretations
+“If an implementation supports a mode with alternative interpretations
for @code{Character} and @code{Wide_Character}, the set of graphic
characters of @code{Character} should nevertheless remain a proper
subset of the set of graphic characters of @code{Wide_Character}. Any
-character set 'localizations' should be reflected in the results of
+character set ‘localizations’ should be reflected in the results of
the subprograms defined in the language-defined package
@code{Characters.Handling} (see A.3) available in such a mode. In a mode with
an alternative interpretation of @code{Character}, the implementation should
also support a corresponding change in what is a legal
-@code{identifier_letter}."
+@code{identifier_letter}.”
@end quotation
Not all wide character modes follow this advice, in particular the JIS
@@ -13853,11 +13911,11 @@ there is no such restriction.
@quotation
-"An implementation should support @code{Long_Integer} in addition to
+“An implementation should support @code{Long_Integer} in addition to
@code{Integer} if the target machine supports 32-bit (or longer)
arithmetic. No other named integer subtypes are recommended for package
@code{Standard}. Instead, appropriate named integer subtypes should be
-provided in the library package @code{Interfaces} (see B.2)."
+provided in the library package @code{Interfaces} (see B.2).”
@end quotation
@code{Long_Integer} is supported. Other standard integer types are supported
@@ -13872,9 +13930,9 @@ types of the machine are easily available.
@quotation
-"An implementation for a two's complement machine should support
+“An implementation for a two’s complement machine should support
modular types with a binary modulus up to @code{System.Max_Int*2+2}. An
-implementation should support a non-binary modules up to @code{Integer'Last}."
+implementation should support a non-binary modules up to @code{Integer'Last}.”
@end quotation
Followed.
@@ -13888,13 +13946,13 @@ Followed.
@quotation
-"For the evaluation of a call on @code{S'Pos} for an enumeration
+“For the evaluation of a call on @code{S'Pos} for an enumeration
subtype, if the value of the operand does not correspond to the internal
code for any enumeration literal of its type (perhaps due to an
un-initialized variable), then the implementation should raise
@code{Program_Error}. This is particularly important for enumeration
types with noncontiguous internal codes specified by an
-enumeration_representation_clause."
+enumeration_representation_clause.”
@end quotation
Followed.
@@ -13908,11 +13966,11 @@ Followed.
@quotation
-"An implementation should support @code{Long_Float} in addition to
+“An implementation should support @code{Long_Float} in addition to
@code{Float} if the target machine supports 11 or more digits of
precision. No other named floating point subtypes are recommended for
package @code{Standard}. Instead, appropriate named floating point subtypes
-should be provided in the library package @code{Interfaces} (see B.2)."
+should be provided in the library package @code{Interfaces} (see B.2).”
@end quotation
@code{Short_Float} and @code{Long_Long_Float} are also provided. The
@@ -13931,57 +13989,57 @@ is a software rather than a hardware format.
@geindex Arrays
@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
+@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{221}
@section RM 3.6.2(11): Multidimensional Arrays
@quotation
-"An implementation should normally represent multidimensional arrays in
+“An implementation should normally represent multidimensional arrays in
row-major order, consistent with the notation used for multidimensional
array aggregates (see 4.3.3). However, if a pragma @code{Convention}
-(@code{Fortran}, ...) applies to a multidimensional array type, then
-column-major order should be used instead (see B.5, @emph{Interfacing with Fortran})."
+(@code{Fortran}, …) applies to a multidimensional array type, then
+column-major order should be used instead (see B.5, @emph{Interfacing with Fortran}).”
@end quotation
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
+@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{222}
-@section RM 9.6(30-31): Duration'Small
+@section RM 9.6(30-31): Duration’Small
@quotation
-"Whenever possible in an implementation, the value of @code{Duration'Small}
-should be no greater than 100 microseconds."
+“Whenever possible in an implementation, the value of @code{Duration'Small}
+should be no greater than 100 microseconds.”
@end quotation
Followed. (@code{Duration'Small} = 10**(-9)).
@quotation
-"The time base for @code{delay_relative_statements} should be monotonic;
-it need not be the same time base as used for @code{Calendar.Clock}."
+“The time base for @code{delay_relative_statements} should be monotonic;
+it need not be the same time base as used for @code{Calendar.Clock}.”
@end quotation
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
+@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{223}
@section RM 10.2.1(12): Consistent Representation
@quotation
-"In an implementation, a type declared in a pre-elaborated package should
+“In an implementation, a type declared in a pre-elaborated package should
have the same representation in every elaboration of a given version of
the package, whether the elaborations occur in distinct executions of
the same program, or in executions of distinct programs or partitions
-that include the given version."
+that include the given version.”
@end quotation
Followed, except in the case of tagged types. Tagged types involve
@@ -13999,18 +14057,18 @@ advice without severely impacting efficiency of execution.
@quotation
-"@code{Exception_Message} by default and @code{Exception_Information}
+“@code{Exception_Message} by default and @code{Exception_Information}
should produce information useful for
debugging. @code{Exception_Message} should be short, about one
line. @code{Exception_Information} can be long. @code{Exception_Message}
should not include the
@code{Exception_Name}. @code{Exception_Information} should include both
-the @code{Exception_Name} and the @code{Exception_Message}."
+the @code{Exception_Name} and the @code{Exception_Message}.”
@end quotation
-Followed. For each exception that doesn't have a specified
+Followed. For each exception that doesn’t have a specified
@code{Exception_Message}, the compiler generates one containing the location
-of the raise statement. This location has the form 'file_name:line', where
+of the raise statement. This location has the form ‘file_name:line’, where
file_name is the short file name (without path information) and line is the line
number in the file. Note that in the case of the Zero Cost Exception
mechanism, these messages become redundant with the Exception_Information that
@@ -14030,8 +14088,8 @@ Pragma @code{Discard_Names}.
@quotation
-"The implementation should minimize the code executed for checks that
-have been suppressed."
+“The implementation should minimize the code executed for checks that
+have been suppressed.”
@end quotation
Followed.
@@ -14045,14 +14103,14 @@ Followed.
@quotation
-"The recommended level of support for all representation items is
+“The recommended level of support for all representation items is
qualified as follows:
An implementation need not support representation items containing
nonstatic expressions, except that an implementation should support a
representation item for a given entity if each nonstatic expression in
the representation item is a name that statically denotes a constant
-declared before the entity."
+declared before the entity.”
@end quotation
Followed. In fact, GNAT goes beyond the recommended level of support
@@ -14079,8 +14137,8 @@ described above.
@quotation
-"An aliased component, or a component whose type is by-reference, should
-always be allocated at an addressable location."
+“An aliased component, or a component whose type is by-reference, should
+always be allocated at an addressable location.”
@end quotation
Followed.
@@ -14094,7 +14152,7 @@ Followed.
@quotation
-"If a type is packed, then the implementation should try to minimize
+“If a type is packed, then the implementation should try to minimize
storage allocated to objects of the type, possibly at the expense of
speed of accessing components, subject to reasonable complexity in
addressing calculations.
@@ -14106,7 +14164,7 @@ possible subject to the Sizes of the component subtypes, and subject to
any @emph{record_representation_clause} that applies to the type; the
implementation may, but need not, reorder components or cross aligned
word boundaries to improve the packing. A component whose @code{Size} is
-greater than the word size may be allocated an integral number of words."
+greater than the word size may be allocated an integral number of words.”
@end quotation
Followed. Tight packing of arrays is supported for all component sizes
@@ -14118,8 +14176,8 @@ subcomponent of the packed type.
@quotation
-"An implementation should support Address clauses for imported
-subprograms."
+“An implementation should support Address clauses for imported
+subprograms.”
@end quotation
Followed.
@@ -14133,19 +14191,19 @@ Followed.
@quotation
-"For an array @code{X}, @code{X'Address} should point at the first
-component of the array, and not at the array bounds."
+“For an array @code{X}, @code{X'Address} should point at the first
+component of the array, and not at the array bounds.”
@end quotation
Followed.
@quotation
-"The recommended level of support for the @code{Address} attribute is:
+“The recommended level of support for the @code{Address} attribute is:
@code{X'Address} should produce a useful result if @code{X} is an
object that is aliased or of a by-reference type, or is an entity whose
-@code{Address} has been specified."
+@code{Address} has been specified.”
@end quotation
Followed. A valid address will be produced even if none of those
@@ -14154,25 +14212,25 @@ memory to ensure the address is valid.
@quotation
-"An implementation should support @code{Address} clauses for imported
-subprograms."
+“An implementation should support @code{Address} clauses for imported
+subprograms.”
@end quotation
Followed.
@quotation
-"Objects (including subcomponents) that are aliased or of a by-reference
-type should be allocated on storage element boundaries."
+“Objects (including subcomponents) that are aliased or of a by-reference
+type should be allocated on storage element boundaries.”
@end quotation
Followed.
@quotation
-"If the @code{Address} of an object is specified, or it is imported or exported,
+“If the @code{Address} of an object is specified, or it is imported or exported,
then the implementation should not perform optimizations based on
-assumptions of no aliases."
+assumptions of no aliases.”
@end quotation
Followed.
@@ -14186,50 +14244,50 @@ Followed.
@quotation
-"The recommended level of support for the @code{Alignment} attribute for
+“The recommended level of support for the @code{Alignment} attribute for
subtypes is:
An implementation should support specified Alignments that are factors
and multiples of the number of storage elements per word, subject to the
-following:"
+following:”
@end quotation
Followed.
@quotation
-"An implementation need not support specified Alignments for
+“An implementation need not support specified Alignments for
combinations of Sizes and Alignments that cannot be easily
-loaded and stored by available machine instructions."
+loaded and stored by available machine instructions.”
@end quotation
Followed.
@quotation
-"An implementation need not support specified Alignments that are
+“An implementation need not support specified Alignments that are
greater than the maximum @code{Alignment} the implementation ever returns by
-default."
+default.”
@end quotation
Followed.
@quotation
-"The recommended level of support for the @code{Alignment} attribute for
+“The recommended level of support for the @code{Alignment} attribute for
objects is:
-Same as above, for subtypes, but in addition:"
+Same as above, for subtypes, but in addition:”
@end quotation
Followed.
@quotation
-"For stand-alone library-level objects of statically constrained
+“For stand-alone library-level objects of statically constrained
subtypes, the implementation should support all alignments
supported by the target linker. For example, page alignment is likely to
-be supported for such objects, but not for subtypes."
+be supported for such objects, but not for subtypes.”
@end quotation
Followed.
@@ -14243,13 +14301,13 @@ Followed.
@quotation
-"The recommended level of support for the @code{Size} attribute of
+“The recommended level of support for the @code{Size} attribute of
objects is:
A @code{Size} clause should be supported for an object if the specified
-@code{Size} is at least as large as its subtype's @code{Size}, and
+@code{Size} is at least as large as its subtype’s @code{Size}, and
corresponds to a size in storage elements that is a multiple of the
-object's @code{Alignment} (if the @code{Alignment} is nonzero)."
+object’s @code{Alignment} (if the @code{Alignment} is nonzero).”
@end quotation
Followed.
@@ -14261,20 +14319,20 @@ Followed.
@quotation
-"If the @code{Size} of a subtype is specified, and allows for efficient
+“If the @code{Size} of a subtype is specified, and allows for efficient
independent addressability (see 9.10) on the target architecture, then
the @code{Size} of the following objects of the subtype should equal the
@code{Size} of the subtype:
-Aliased objects (including components)."
+Aliased objects (including components).”
@end quotation
Followed.
@quotation
-"@cite{Size} clause on a composite subtype should not affect the
-internal layout of components."
+“@cite{Size} clause on a composite subtype should not affect the
+internal layout of components.”
@end quotation
Followed. But note that this can be overridden by use of the implementation
@@ -14282,23 +14340,23 @@ pragma Implicit_Packing in the case of packed arrays.
@quotation
-"The recommended level of support for the @code{Size} attribute of subtypes is:
+“The recommended level of support for the @code{Size} attribute of subtypes is:
The @code{Size} (if not specified) of a static discrete or fixed point
subtype should be the number of bits needed to represent each value
belonging to the subtype using an unbiased representation, leaving space
for a sign bit only if the subtype contains negative values. If such a
subtype is a first subtype, then an implementation should support a
-specified @code{Size} for it that reflects this representation."
+specified @code{Size} for it that reflects this representation.”
@end quotation
Followed.
@quotation
-"For a subtype implemented with levels of indirection, the @code{Size}
+“For a subtype implemented with levels of indirection, the @code{Size}
should include the size of the pointers, but not the size of what they
-point at."
+point at.”
@end quotation
Followed.
@@ -14312,24 +14370,24 @@ Followed.
@quotation
-"The recommended level of support for the @code{Component_Size}
+“The recommended level of support for the @code{Component_Size}
attribute is:
An implementation need not support specified @code{Component_Sizes} that are
-less than the @code{Size} of the component subtype."
+less than the @code{Size} of the component subtype.”
@end quotation
Followed.
@quotation
-"An implementation should support specified Component_Sizes that
+“An implementation should support specified Component_Sizes that
are factors and multiples of the word size. For such
Component_Sizes, the array should contain no gaps between
components. For other Component_Sizes (if supported), the array
should contain no gaps between components when packing is also
specified; the implementation should forbid this combination in cases
-where it cannot support a no-gaps representation."
+where it cannot support a no-gaps representation.”
@end quotation
Followed.
@@ -14346,12 +14404,12 @@ Followed.
@quotation
-"The recommended level of support for enumeration representation clauses
+“The recommended level of support for enumeration representation clauses
is:
An implementation need not support enumeration representation clauses
for boolean types, but should at minimum support the internal codes in
-the range @code{System.Min_Int .. System.Max_Int}."
+the range @code{System.Min_Int .. System.Max_Int}.”
@end quotation
Followed.
@@ -14368,52 +14426,52 @@ Followed.
@quotation
-"The recommended level of support for
+“The recommended level of support for
@emph{record_representation_clause}s is:
An implementation should support storage places that can be extracted
with a load, mask, shift sequence of machine code, and set with a load,
shift, mask, store sequence, given the available machine instructions
-and run-time model."
+and run-time model.”
@end quotation
Followed.
@quotation
-"A storage place should be supported if its size is equal to the
+“A storage place should be supported if its size is equal to the
@code{Size} of the component subtype, and it starts and ends on a
-boundary that obeys the @code{Alignment} of the component subtype."
+boundary that obeys the @code{Alignment} of the component subtype.”
@end quotation
Followed.
@quotation
-"If the default bit ordering applies to the declaration of a given type,
-then for a component whose subtype's @code{Size} is less than the word
+“If the default bit ordering applies to the declaration of a given type,
+then for a component whose subtype’s @code{Size} is less than the word
size, any storage place that does not cross an aligned word boundary
-should be supported."
+should be supported.”
@end quotation
Followed.
@quotation
-"An implementation may reserve a storage place for the tag field of a
-tagged type, and disallow other components from overlapping that place."
+“An implementation may reserve a storage place for the tag field of a
+tagged type, and disallow other components from overlapping that place.”
@end quotation
Followed. The storage place for the tag field is the beginning of the tagged
-record, and its size is Address'Size. GNAT will reject an explicit component
+record, and its size is Address’Size. GNAT will reject an explicit component
clause for the tag field.
@quotation
-"An implementation need not support a @emph{component_clause} for a
+“An implementation need not support a @emph{component_clause} for a
component of an extension part if the storage place is not after the
storage places of all components of the parent type, whether or not
-those storage places had been specified."
+those storage places had been specified.”
@end quotation
Followed. The above advice on record representation clauses is followed,
@@ -14428,13 +14486,13 @@ and all mentioned features are implemented.
@quotation
-"If a component is represented using some form of pointer (such as an
+“If a component is represented using some form of pointer (such as an
offset) to the actual data of the component, and this data is contiguous
with the rest of the object, then the storage place attributes should
reflect the place of the actual data, not the pointer. If a component is
allocated discontinuously from the rest of the object, then a warning
should be generated upon reference to one of its storage place
-attributes."
+attributes.”
@end quotation
Followed. There are no such components in GNAT.
@@ -14448,11 +14506,11 @@ Followed. There are no such components in GNAT.
@quotation
-"The recommended level of support for the non-default bit ordering is:
+“The recommended level of support for the non-default bit ordering is:
If @code{Word_Size} = @code{Storage_Unit}, then the implementation
should support the non-default bit ordering in addition to the default
-bit ordering."
+bit ordering.”
@end quotation
Followed. Word size does not equal storage size in this implementation.
@@ -14468,7 +14526,7 @@ Thus non-default bit ordering is not supported.
@quotation
-"@cite{Address} should be of a private type."
+“@cite{Address} should be of a private type.”
@end quotation
Followed.
@@ -14486,10 +14544,10 @@ Followed.
@quotation
-"Operations in @code{System} and its children should reflect the target
+“Operations in @code{System} and its children should reflect the target
environment semantics as closely as is reasonable. For example, on most
-machines, it makes sense for address arithmetic to 'wrap around'.
-Operations that do not make sense should raise @code{Program_Error}."
+machines, it makes sense for address arithmetic to ‘wrap around’.
+Operations that do not make sense should raise @code{Program_Error}.”
@end quotation
Followed. Address arithmetic is modular arithmetic that wraps around. No
@@ -14504,19 +14562,19 @@ operation raises @code{Program_Error}, since all operations make sense.
@quotation
-"The @code{Size} of an array object should not include its bounds; hence,
-the bounds should not be part of the converted data."
+“The @code{Size} of an array object should not include its bounds; hence,
+the bounds should not be part of the converted data.”
@end quotation
Followed.
@quotation
-"The implementation should not generate unnecessary run-time checks to
+“The implementation should not generate unnecessary run-time checks to
ensure that the representation of @code{S} is a representation of the
target type. It should take advantage of the permission to return by
reference when possible. Restrictions on unchecked conversions should be
-avoided unless required by the target environment."
+avoided unless required by the target environment.”
@end quotation
Followed. There are no restrictions on unchecked conversion. A warning is
@@ -14525,7 +14583,7 @@ the semantics in this case may be target dependent.
@quotation
-"The recommended level of support for unchecked conversions is:
+“The recommended level of support for unchecked conversions is:
Unchecked conversions should be supported and should be reversible in
the cases where this clause defines the result. To enable meaningful use
@@ -14533,7 +14591,7 @@ of unchecked conversion, a contiguous representation should be used for
elementary subtypes, for statically constrained array subtypes whose
component subtype is one of the subtypes described in this paragraph,
and for record subtypes without discriminants whose component subtypes
-are described in this paragraph."
+are described in this paragraph.”
@end quotation
Followed.
@@ -14548,9 +14606,9 @@ Followed.
@quotation
-"An implementation should document any cases in which it dynamically
+“An implementation should document any cases in which it dynamically
allocates heap storage for a purpose other than the evaluation of an
-allocator."
+allocator.”
@end quotation
Followed, the only other points at which heap storage is dynamically
@@ -14574,18 +14632,18 @@ stack is used for returning variable length results.
@quotation
-"A default (implementation-provided) storage pool for an
+“A default (implementation-provided) storage pool for an
access-to-constant type should not have overhead to support deallocation of
-individual objects."
+individual objects.”
@end quotation
Followed.
@quotation
-"A storage pool for an anonymous access type should be created at the
+“A storage pool for an anonymous access type should be created at the
point of an allocator for the type, and be reclaimed when the designated
-object becomes inaccessible."
+object becomes inaccessible.”
@end quotation
Followed.
@@ -14599,8 +14657,8 @@ Followed.
@quotation
-"For a standard storage pool, @code{Free} should actually reclaim the
-storage."
+“For a standard storage pool, @code{Free} should actually reclaim the
+storage.”
@end quotation
Followed.
@@ -14614,11 +14672,11 @@ Followed.
@quotation
-"If not specified, the value of Stream_Size for an elementary type
+“If not specified, the value of Stream_Size for an elementary type
should be the number of bits that corresponds to the minimum number of
stream elements required by the first subtype of the type, rounded up
to the nearest factor or multiple of the word size that is also a
-multiple of the stream element size."
+multiple of the stream element size.”
@end quotation
Followed, except that the number of stream elements is 1, 2, 3, 4 or 8.
@@ -14645,11 +14703,11 @@ scalar types. This XDR alternative can be enabled via the binder switch -xdr.
@quotation
-"If an implementation provides additional named predefined integer types,
+“If an implementation provides additional named predefined integer types,
then the names should end with @code{Integer} as in
@code{Long_Integer}. If an implementation provides additional named
predefined floating point types, then the names should end with
-@code{Float} as in @code{Long_Float}."
+@code{Float} as in @code{Long_Float}.”
@end quotation
Followed.
@@ -14663,10 +14721,10 @@ Followed.
@quotation
-"If an implementation provides a localized definition of @code{Character}
+“If an implementation provides a localized definition of @code{Character}
or @code{Wide_Character}, then the effects of the subprograms in
@code{Characters.Handling} should reflect the localizations.
-See also 3.5.2."
+See also 3.5.2.”
@end quotation
Followed. GNAT provides no such localized definitions.
@@ -14680,8 +14738,8 @@ Followed. GNAT provides no such localized definitions.
@quotation
-"Bounded string objects should not be implemented by implicit pointers
-and dynamic allocation."
+“Bounded string objects should not be implemented by implicit pointers
+and dynamic allocation.”
@end quotation
Followed. No implicit pointers or dynamic allocation are used.
@@ -14695,21 +14753,21 @@ Followed. No implicit pointers or dynamic allocation are used.
@quotation
-"Any storage associated with an object of type @code{Generator} should be
-reclaimed on exit from the scope of the object."
+“Any storage associated with an object of type @code{Generator} should be
+reclaimed on exit from the scope of the object.”
@end quotation
Followed.
@quotation
-"If the generator period is sufficiently long in relation to the number
+“If the generator period is sufficiently long in relation to the number
of distinct initiator values, then each possible value of
@code{Initiator} passed to @code{Reset} should initiate a sequence of
random numbers that does not, in a practical sense, overlap the sequence
initiated by any other value. If this is not possible, then the mapping
between initiator values and generator states should be a rapidly
-varying function of the initiator value."
+varying function of the initiator value.”
@end quotation
Followed. The generator period is sufficiently long for the first
@@ -14724,13 +14782,13 @@ condition here to hold true.
@quotation
-"The @code{Get_Immediate} procedures should be implemented with
+“The @code{Get_Immediate} procedures should be implemented with
unbuffered input. For a device such as a keyboard, input should be
available if a key has already been typed, whereas for a disk
file, input should always be available except at end of file. For a file
associated with a keyboard-like device, any line-editing features of the
underlying operating system should be disabled during the execution of
-@code{Get_Immediate}."
+@code{Get_Immediate}.”
@end quotation
Followed on all targets except VxWorks. For VxWorks, there is no way to
@@ -14752,7 +14810,7 @@ section A.18 and its subsections) is followed except for A.18.24(17):
@quotation
-"Bounded ordered set objects should be implemented without implicit pointers or dynamic allocation. "
+“Bounded ordered set objects should be implemented without implicit pointers or dynamic allocation. “
@end quotation
The implementations of the two Reference_Preserving_Key functions of
@@ -14769,7 +14827,7 @@ follow the implementation advice.
@quotation
-"If an implementation supports pragma @code{Export} to a given language,
+“If an implementation supports pragma @code{Export} to a given language,
then it should also allow the main subprogram to be written in that
language. It should support some mechanism for invoking the elaboration
of the Ada library units included in the system, and for invoking the
@@ -14778,15 +14836,15 @@ recommended mechanism is to provide two subprograms whose link names are
@code{adainit} and @code{adafinal}. @code{adainit} should contain the
elaboration code for library units. @code{adafinal} should contain the
finalization code. These subprograms should have no effect the second
-and subsequent time they are called."
+and subsequent time they are called.”
@end quotation
Followed.
@quotation
-"Automatic elaboration of pre-elaborated packages should be
-provided when pragma @code{Export} is supported."
+“Automatic elaboration of pre-elaborated packages should be
+provided when pragma @code{Export} is supported.”
@end quotation
Followed when the main program is in Ada. If the main program is in a
@@ -14796,12 +14854,12 @@ packages.
@quotation
-"For each supported convention @emph{L} other than @code{Intrinsic}, an
+“For each supported convention @emph{L} other than @code{Intrinsic}, an
implementation should support @code{Import} and @code{Export} pragmas
for objects of @emph{L}-compatible types and for subprograms, and pragma
@cite{Convention} for @emph{L}-eligible types and for subprograms,
presuming the other language has corresponding features. Pragma
-@code{Convention} need not be supported for scalar types."
+@code{Convention} need not be supported for scalar types.”
@end quotation
Followed.
@@ -14817,22 +14875,22 @@ Followed.
@quotation
-"For each implementation-defined convention identifier, there should be a
+“For each implementation-defined convention identifier, there should be a
child package of package Interfaces with the corresponding name. This
package should contain any declarations that would be useful for
interfacing to the language (implementation) represented by the
convention. Any declarations useful for interfacing to any language on
the given hardware architecture should be provided directly in
-@code{Interfaces}."
+@code{Interfaces}.”
@end quotation
Followed.
@quotation
-"An implementation supporting an interface to C, COBOL, or Fortran should
+“An implementation supporting an interface to C, COBOL, or Fortran should
provide the corresponding package or packages described in the following
-clauses."
+clauses.”
@end quotation
Followed. GNAT provides all the packages described in this section.
@@ -14847,60 +14905,60 @@ Followed. GNAT provides all the packages described in this section.
@quotation
-"An implementation should support the following interface correspondences
-between Ada and C."
+“An implementation should support the following interface correspondences
+between Ada and C.”
@end quotation
Followed.
@quotation
-"An Ada procedure corresponds to a void-returning C function."
+“An Ada procedure corresponds to a void-returning C function.”
@end quotation
Followed.
@quotation
-"An Ada function corresponds to a non-void C function."
+“An Ada function corresponds to a non-void C function.”
@end quotation
Followed.
@quotation
-"An Ada @code{in} scalar parameter is passed as a scalar argument to a C
-function."
+“An Ada @code{in} scalar parameter is passed as a scalar argument to a C
+function.”
@end quotation
Followed.
@quotation
-"An Ada @code{in} parameter of an access-to-object type with designated
+“An Ada @code{in} parameter of an access-to-object type with designated
type @code{T} is passed as a @code{t*} argument to a C function,
-where @code{t} is the C type corresponding to the Ada type @code{T}."
+where @code{t} is the C type corresponding to the Ada type @code{T}.”
@end quotation
Followed.
@quotation
-"An Ada access @code{T} parameter, or an Ada @code{out} or @code{in out}
+“An Ada access @code{T} parameter, or an Ada @code{out} or @code{in out}
parameter of an elementary type @code{T}, is passed as a @code{t*}
argument to a C function, where @code{t} is the C type corresponding to
the Ada type @code{T}. In the case of an elementary @code{out} or
@code{in out} parameter, a pointer to a temporary copy is used to
-preserve by-copy semantics."
+preserve by-copy semantics.”
@end quotation
Followed.
@quotation
-"An Ada parameter of a record type @code{T}, of any mode, is passed as a
+“An Ada parameter of a record type @code{T}, of any mode, is passed as a
@code{t*} argument to a C function, where @code{t} is the C
-structure corresponding to the Ada type @code{T}."
+structure corresponding to the Ada type @code{T}.”
@end quotation
Followed. This convention may be overridden by the use of the C_Pass_By_Copy
@@ -14909,18 +14967,18 @@ call using an extended import or export pragma.
@quotation
-"An Ada parameter of an array type with component type @code{T}, of any
+“An Ada parameter of an array type with component type @code{T}, of any
mode, is passed as a @code{t*} argument to a C function, where
-@code{t} is the C type corresponding to the Ada type @code{T}."
+@code{t} is the C type corresponding to the Ada type @code{T}.”
@end quotation
Followed.
@quotation
-"An Ada parameter of an access-to-subprogram type is passed as a pointer
+“An Ada parameter of an access-to-subprogram type is passed as a pointer
to a C function whose prototype corresponds to the designated
-subprogram's specification."
+subprogram’s specification.”
@end quotation
Followed.
@@ -14935,33 +14993,33 @@ Followed.
@quotation
-"An Ada implementation should support the following interface
-correspondences between Ada and COBOL."
+“An Ada implementation should support the following interface
+correspondences between Ada and COBOL.”
@end quotation
Followed.
@quotation
-"An Ada access @code{T} parameter is passed as a @code{BY REFERENCE} data item of
-the COBOL type corresponding to @code{T}."
+“An Ada access @code{T} parameter is passed as a @code{BY REFERENCE} data item of
+the COBOL type corresponding to @code{T}.”
@end quotation
Followed.
@quotation
-"An Ada in scalar parameter is passed as a @code{BY CONTENT} data item of
-the corresponding COBOL type."
+“An Ada in scalar parameter is passed as a @code{BY CONTENT} data item of
+the corresponding COBOL type.”
@end quotation
Followed.
@quotation
-"Any other Ada parameter is passed as a @code{BY REFERENCE} data item of the
+“Any other Ada parameter is passed as a @code{BY REFERENCE} data item of the
COBOL type corresponding to the Ada parameter type; for scalars, a local
-copy is used if necessary to ensure by-copy semantics."
+copy is used if necessary to ensure by-copy semantics.”
@end quotation
Followed.
@@ -14976,44 +15034,44 @@ Followed.
@quotation
-"An Ada implementation should support the following interface
-correspondences between Ada and Fortran:"
+“An Ada implementation should support the following interface
+correspondences between Ada and Fortran:”
@end quotation
Followed.
@quotation
-"An Ada procedure corresponds to a Fortran subroutine."
+“An Ada procedure corresponds to a Fortran subroutine.”
@end quotation
Followed.
@quotation
-"An Ada function corresponds to a Fortran function."
+“An Ada function corresponds to a Fortran function.”
@end quotation
Followed.
@quotation
-"An Ada parameter of an elementary, array, or record type @code{T} is
+“An Ada parameter of an elementary, array, or record type @code{T} is
passed as a @code{T} argument to a Fortran procedure, where @code{T} is
the Fortran type corresponding to the Ada type @code{T}, and where the
INTENT attribute of the corresponding dummy argument matches the Ada
-formal parameter mode; the Fortran implementation's parameter passing
+formal parameter mode; the Fortran implementation’s parameter passing
conventions are used. For elementary types, a local copy is used if
-necessary to ensure by-copy semantics."
+necessary to ensure by-copy semantics.”
@end quotation
Followed.
@quotation
-"An Ada parameter of an access-to-subprogram type is passed as a
+“An Ada parameter of an access-to-subprogram type is passed as a
reference to a Fortran procedure whose interface corresponds to the
-designated subprogram's specification."
+designated subprogram’s specification.”
@end quotation
Followed.
@@ -15027,30 +15085,30 @@ Followed.
@quotation
-"The machine code or intrinsic support should allow access to all
+“The machine code or intrinsic support should allow access to all
operations normally available to assembly language programmers for the
-target environment, including privileged instructions, if any."
+target environment, including privileged instructions, if any.”
@end quotation
Followed.
@quotation
-"The interfacing pragmas (see Annex B) should support interface to
+“The interfacing pragmas (see Annex B) should support interface to
assembler; the default assembler should be associated with the
-convention identifier @code{Assembler}."
+convention identifier @code{Assembler}.”
@end quotation
Followed.
@quotation
-"If an entity is exported to assembly language, then the implementation
+“If an entity is exported to assembly language, then the implementation
should allocate it at an addressable location, and should ensure that it
is retained by the linking process, even if not otherwise referenced
from the Ada code. The implementation should assume that any call to a
machine code or assembler subprogram is allowed to read or update every
-object that is specified as exported."
+object that is specified as exported.”
@end quotation
Followed.
@@ -15062,54 +15120,54 @@ Followed.
@quotation
-"The implementation should ensure that little or no overhead is
-associated with calling intrinsic and machine-code subprograms."
+“The implementation should ensure that little or no overhead is
+associated with calling intrinsic and machine-code subprograms.”
@end quotation
Followed for both intrinsics and machine-code subprograms.
@quotation
-"It is recommended that intrinsic subprograms be provided for convenient
+“It is recommended that intrinsic subprograms be provided for convenient
access to any machine operations that provide special capabilities or
efficiency and that are not otherwise available through the language
-constructs."
+constructs.”
@end quotation
Followed. A full set of machine operation intrinsic subprograms is provided.
@quotation
-"Atomic read-modify-write operations---e.g., test and set, compare and
-swap, decrement and test, enqueue/dequeue."
+“Atomic read-modify-write operations—e.g., test and set, compare and
+swap, decrement and test, enqueue/dequeue.”
@end quotation
Followed on any target supporting such operations.
@quotation
-"Standard numeric functions---e.g.:, sin, log."
+“Standard numeric functions—e.g.:, sin, log.”
@end quotation
Followed on any target supporting such operations.
@quotation
-"String manipulation operations---e.g.:, translate and test."
+“String manipulation operations—e.g.:, translate and test.”
@end quotation
Followed on any target supporting such operations.
@quotation
-"Vector operations---e.g.:, compare vector against thresholds."
+“Vector operations—e.g.:, compare vector against thresholds.”
@end quotation
Followed on any target supporting such operations.
@quotation
-"Direct operations on I/O ports."
+“Direct operations on I/O ports.”
@end quotation
Followed on any target supporting such operations.
@@ -15123,10 +15181,10 @@ Followed on any target supporting such operations.
@quotation
-"If the @code{Ceiling_Locking} policy is not in effect, the
+“If the @code{Ceiling_Locking} policy is not in effect, the
implementation should provide means for the application to specify which
interrupts are to be blocked during protected actions, if the underlying
-system allows for a finer-grain control of interrupt blocking."
+system allows for a finer-grain control of interrupt blocking.”
@end quotation
Followed. The underlying system does not allow for finer-grain control
@@ -15141,8 +15199,8 @@ of interrupt blocking.
@quotation
-"Whenever possible, the implementation should allow interrupt handlers to
-be called directly by the hardware."
+“Whenever possible, the implementation should allow interrupt handlers to
+be called directly by the hardware.”
@end quotation
Followed on any target where the underlying operating system permits
@@ -15150,8 +15208,8 @@ such direct calls.
@quotation
-"Whenever practical, violations of any
-implementation-defined restrictions should be detected before run time."
+“Whenever practical, violations of any
+implementation-defined restrictions should be detected before run time.”
@end quotation
Followed. Compile time warnings are given when possible.
@@ -15167,11 +15225,11 @@ Followed. Compile time warnings are given when possible.
@quotation
-"If implementation-defined forms of interrupt handler procedures are
+“If implementation-defined forms of interrupt handler procedures are
supported, such as protected procedures with parameters, then for each
such form of a handler, a type analogous to @code{Parameterless_Handler}
should be specified in a child package of @code{Interrupts}, with the
-same operations as in the predefined package Interrupts."
+same operations as in the predefined package Interrupts.”
@end quotation
Followed.
@@ -15185,10 +15243,10 @@ Followed.
@quotation
-"It is recommended that pre-elaborated packages be implemented in such a
+“It is recommended that pre-elaborated packages be implemented in such a
way that there should be little or no code executed at run time for the
elaboration of entities not already covered by the Implementation
-Requirements."
+Requirements.”
@end quotation
Followed. Executable code is generated in some cases, e.g., loops
@@ -15201,9 +15259,9 @@ to initialize large arrays.
@quotation
-"If the pragma applies to an entity, then the implementation should
+“If the pragma applies to an entity, then the implementation should
reduce the amount of storage used for storing names associated with that
-entity."
+entity.”
@end quotation
Followed.
@@ -15219,14 +15277,14 @@ Followed.
@quotation
-"Some implementations are targeted to domains in which memory use at run
+“Some implementations are targeted to domains in which memory use at run
time must be completely deterministic. For such implementations, it is
recommended that the storage for task attributes will be pre-allocated
statically and not from the heap. This can be accomplished by either
-placing restrictions on the number and the size of the task's
+placing restrictions on the number and the size of the task’s
attributes, or by using the pre-allocated storage for the first @code{N}
attribute objects, and the heap for the others. In the latter case,
-@code{N} should be documented."
+@code{N} should be documented.”
@end quotation
Not followed. This implementation is not targeted to such a domain.
@@ -15240,8 +15298,8 @@ Not followed. This implementation is not targeted to such a domain.
@quotation
-"The implementation should use names that end with @code{_Locking} for
-locking policies defined by the implementation."
+“The implementation should use names that end with @code{_Locking} for
+locking policies defined by the implementation.”
@end quotation
Followed. Two implementation-defined locking policies are defined,
@@ -15257,8 +15315,8 @@ whose names (@code{Inheritance_Locking} and
@quotation
-"Names that end with @code{_Queuing} should be used
-for all implementation-defined queuing policies."
+“Names that end with @code{_Queuing} should be used
+for all implementation-defined queuing policies.”
@end quotation
Followed. No such implementation-defined queuing policies exist.
@@ -15272,19 +15330,19 @@ Followed. No such implementation-defined queuing policies exist.
@quotation
-"Even though the @emph{abort_statement} is included in the list of
+“Even though the @emph{abort_statement} is included in the list of
potentially blocking operations (see 9.5.1), it is recommended that this
statement be implemented in a way that never requires the task executing
-the @emph{abort_statement} to block."
+the @emph{abort_statement} to block.”
@end quotation
Followed.
@quotation
-"On a multi-processor, the delay associated with aborting a task on
+“On a multi-processor, the delay associated with aborting a task on
another processor should be bounded; the implementation should use
-periodic polling, if necessary, to achieve this."
+periodic polling, if necessary, to achieve this.”
@end quotation
Followed.
@@ -15298,8 +15356,8 @@ Followed.
@quotation
-"When feasible, the implementation should take advantage of the specified
-restrictions to produce a more efficient implementation."
+“When feasible, the implementation should take advantage of the specified
+restrictions to produce a more efficient implementation.”
@end quotation
GNAT currently takes advantage of these restrictions by providing an optimized
@@ -15317,8 +15375,8 @@ pragma @code{Profile (Restricted)} for more details.
@quotation
-"When appropriate, implementations should provide configuration
-mechanisms to change the value of @code{Tick}."
+“When appropriate, implementations should provide configuration
+mechanisms to change the value of @code{Tick}.”
@end quotation
Such configuration mechanisms are not appropriate to this implementation
@@ -15326,17 +15384,17 @@ and are thus not supported.
@quotation
-"It is recommended that @code{Calendar.Clock} and @code{Real_Time.Clock}
-be implemented as transformations of the same time base."
+“It is recommended that @code{Calendar.Clock} and @code{Real_Time.Clock}
+be implemented as transformations of the same time base.”
@end quotation
Followed.
@quotation
-"It is recommended that the best time base which exists in
+“It is recommended that the best time base which exists in
the underlying system be available to the application through
-@code{Clock}. @cite{Best} may mean highest accuracy or largest range."
+@code{Clock}. @cite{Best} may mean highest accuracy or largest range.”
@end quotation
Followed.
@@ -15352,10 +15410,10 @@ Followed.
@quotation
-"Whenever possible, the PCS on the called partition should allow for
+“Whenever possible, the PCS on the called partition should allow for
multiple tasks to call the RPC-receiver with different messages and
should allow them to block until the corresponding subprogram body
-returns."
+returns.”
@end quotation
Followed by GLADE, a separately supplied PCS that can be used with
@@ -15363,9 +15421,9 @@ GNAT.
@quotation
-"The @code{Write} operation on a stream of type @code{Params_Stream_Type}
+“The @code{Write} operation on a stream of type @code{Params_Stream_Type}
should raise @code{Storage_Error} if it runs out of space trying to
-write the @code{Item} into the stream."
+write the @code{Item} into the stream.”
@end quotation
Followed by GLADE, a separately supplied PCS that can be used with
@@ -15380,13 +15438,13 @@ GNAT.
@quotation
-"If COBOL (respectively, C) is widely supported in the target
+“If COBOL (respectively, C) is widely supported in the target
environment, implementations supporting the Information Systems Annex
should provide the child package @code{Interfaces.COBOL} (respectively,
@code{Interfaces.C}) specified in Annex B and should support a
@code{convention_identifier} of COBOL (respectively, C) in the interfacing
pragmas (see Annex B), thus allowing Ada programs to interface with
-programs written in that language."
+programs written in that language.”
@end quotation
Followed.
@@ -15400,11 +15458,11 @@ Followed.
@quotation
-"Packed decimal should be used as the internal representation for objects
-of subtype @code{S} when @code{S}'Machine_Radix = 10."
+“Packed decimal should be used as the internal representation for objects
+of subtype @code{S} when @code{S}’Machine_Radix = 10.”
@end quotation
-Not followed. GNAT ignores @code{S}'Machine_Radix and always uses binary
+Not followed. GNAT ignores @code{S}’Machine_Radix and always uses binary
representations.
@geindex Numerics
@@ -15416,13 +15474,13 @@ representations.
@quotation
-"If Fortran (respectively, C) is widely supported in the target
+“If Fortran (respectively, C) is widely supported in the target
environment, implementations supporting the Numerics Annex
should provide the child package @code{Interfaces.Fortran} (respectively,
@code{Interfaces.C}) specified in Annex B and should support a
@code{convention_identifier} of Fortran (respectively, C) in the interfacing
pragmas (see Annex B), thus allowing Ada programs to interface with
-programs written in that language."
+programs written in that language.”
@end quotation
Followed.
@@ -15436,7 +15494,7 @@ Followed.
@quotation
-"Because the usual mathematical meaning of multiplication of a complex
+“Because the usual mathematical meaning of multiplication of a complex
operand and a real operand is that of the scaling of both components of
the former by the latter, an implementation should not perform this
operation by first promoting the real operand to complex type and then
@@ -15448,14 +15506,14 @@ component by the zero component obtained during promotion yields a NaN
that propagates into the final result.) Analogous advice applies in the
case of multiplication of a complex operand and a pure-imaginary
operand, and in the case of division of a complex operand by a real or
-pure-imaginary operand."
+pure-imaginary operand.”
@end quotation
Not followed.
@quotation
-"Similarly, because the usual mathematical meaning of addition of a
+“Similarly, because the usual mathematical meaning of addition of a
complex operand and a real operand is that the imaginary operand remains
unchanged, an implementation should not perform this operation by first
promoting the real operand to complex type and then performing a full
@@ -15468,14 +15526,14 @@ operand is a negatively signed zero. (Explicit addition of the negative
zero to the zero obtained during promotion yields a positive zero.)
Analogous advice applies in the case of addition of a complex operand
and a pure-imaginary operand, and in the case of subtraction of a
-complex operand and a real or pure-imaginary operand."
+complex operand and a real or pure-imaginary operand.”
@end quotation
Not followed.
@quotation
-"Implementations in which @code{Real'Signed_Zeros} is @code{True} should
+“Implementations in which @code{Real'Signed_Zeros} is @code{True} should
attempt to provide a rational treatment of the signs of zero results and
result components. As one example, the result of the @code{Argument}
function should have the sign of the imaginary component of the
@@ -15484,7 +15542,7 @@ the positive real axis; as another, the sign of the imaginary component
of the @code{Compose_From_Polar} function should be the same as
(respectively, the opposite of) that of the @code{Argument} parameter when that
parameter has a value of zero and the @code{Modulus} parameter has a
-nonnegative (respectively, negative) value."
+nonnegative (respectively, negative) value.”
@end quotation
Followed.
@@ -15498,7 +15556,7 @@ Followed.
@quotation
-"Implementations in which @code{Complex_Types.Real'Signed_Zeros} is
+“Implementations in which @code{Complex_Types.Real'Signed_Zeros} is
@code{True} should attempt to provide a rational treatment of the signs
of zero results and result components. For example, many of the complex
elementary functions have components that are odd functions of one of
@@ -15506,7 +15564,7 @@ the parameter components; in these cases, the result component should
have the sign of the parameter component at the origin. Other complex
elementary functions have zero components whose sign is opposite that of
a parameter component at the origin, or is always positive or always
-negative."
+negative.”
@end quotation
Followed.
@@ -15520,14 +15578,14 @@ Followed.
@quotation
-"The versions of the forward trigonometric functions without a
+“The versions of the forward trigonometric functions without a
@code{Cycle} parameter should not be implemented by calling the
corresponding version with a @code{Cycle} parameter of
@code{2.0*Numerics.Pi}, since this will not provide the required
accuracy in some portions of the domain. For the same reason, the
version of @code{Log} without a @code{Base} parameter should not be
implemented by calling the corresponding version with a @code{Base}
-parameter of @code{Numerics.e}."
+parameter of @code{Numerics.e}.”
@end quotation
Followed.
@@ -15544,11 +15602,11 @@ Followed.
@quotation
-"The version of the @code{Compose_From_Polar} function without a
+“The version of the @code{Compose_From_Polar} function without a
@code{Cycle} parameter should not be implemented by calling the
corresponding version with a @code{Cycle} parameter of
@code{2.0*Numerics.Pi}, since this will not provide the required
-accuracy in some portions of the domain."
+accuracy in some portions of the domain.”
@end quotation
Followed.
@@ -15562,16 +15620,16 @@ Followed.
@quotation
-"If the partition elaboration policy is @code{Sequential} and the
+“If the partition elaboration policy is @code{Sequential} and the
Environment task becomes permanently blocked during elaboration then the
partition is deadlocked and it is recommended that the partition be
-immediately terminated."
+immediately terminated.”
@end quotation
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{258}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{259}
+@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{258}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{259}@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}
@chapter Implementation Defined Characteristics
@@ -15596,8 +15654,8 @@ Reference Manual.
@itemize *
@item
-"Whether or not each recommendation given in Implementation
-Advice is followed. See 1.1.2(37)."
+“Whether or not each recommendation given in Implementation
+Advice is followed. See 1.1.2(37).”
@end itemize
See @ref{a,,Implementation Advice}.
@@ -15606,7 +15664,7 @@ See @ref{a,,Implementation Advice}.
@itemize *
@item
-"Capacity limitations of the implementation. See 1.1.3(3)."
+“Capacity limitations of the implementation. See 1.1.3(3).”
@end itemize
The complexity of programs that can be processed is limited only by the
@@ -15617,8 +15675,8 @@ generated object files.
@itemize *
@item
-"Variations from the standard that are impractical to avoid
-given the implementation's execution environment. See 1.1.3(6)."
+“Variations from the standard that are impractical to avoid
+given the implementation’s execution environment. See 1.1.3(6).”
@end itemize
There are no variations from the standard.
@@ -15627,8 +15685,8 @@ There are no variations from the standard.
@itemize *
@item
-"Which code_statements cause external
-interactions. See 1.1.3(10)."
+“Which code_statements cause external
+interactions. See 1.1.3(10).”
@end itemize
Any @emph{code_statement} can potentially cause external interactions.
@@ -15637,8 +15695,8 @@ Any @emph{code_statement} can potentially cause external interactions.
@itemize *
@item
-"The coded representation for the text of an Ada
-program. See 2.1(4)."
+“The coded representation for the text of an Ada
+program. See 2.1(4).”
@end itemize
See separate section on source representation.
@@ -15647,7 +15705,7 @@ See separate section on source representation.
@itemize *
@item
-"The control functions allowed in comments. See 2.1(14)."
+“The control functions allowed in comments. See 2.1(14).”
@end itemize
See separate section on source representation.
@@ -15656,7 +15714,7 @@ See separate section on source representation.
@itemize *
@item
-"The representation for an end of line. See 2.2(2)."
+“The representation for an end of line. See 2.2(2).”
@end itemize
See separate section on source representation.
@@ -15665,8 +15723,8 @@ See separate section on source representation.
@itemize *
@item
-"Maximum supported line length and lexical element
-length. See 2.2(15)."
+“Maximum supported line length and lexical element
+length. See 2.2(15).”
@end itemize
The maximum line length is 255 characters and the maximum length of
@@ -15680,7 +15738,7 @@ length of a lexical element is the same as the maximum line length.
@itemize *
@item
-"Implementation defined pragmas. See 2.8(14)."
+“Implementation defined pragmas. See 2.8(14).”
@end itemize
See @ref{7,,Implementation Defined Pragmas}.
@@ -15689,7 +15747,7 @@ See @ref{7,,Implementation Defined Pragmas}.
@itemize *
@item
-"Effect of pragma @code{Optimize}. See 2.8(27)."
+“Effect of pragma @code{Optimize}. See 2.8(27).”
@end itemize
Pragma @code{Optimize}, if given with a @code{Time} or @code{Space}
@@ -15700,10 +15758,10 @@ not.
@itemize *
@item
-"The sequence of characters of the value returned by
+“The sequence of characters of the value returned by
@code{S'Image} when some of the graphic characters of
@code{S'Wide_Image} are not defined in @code{Character}. See
-3.5(37)."
+3.5(37).”
@end itemize
The sequence of characters is as defined by the wide character encoding
@@ -15714,8 +15772,8 @@ further details.
@itemize *
@item
-"The predefined integer types declared in
-@code{Standard}. See 3.5.4(25)."
+“The predefined integer types declared in
+@code{Standard}. See 3.5.4(25).”
@end itemize
@@ -15786,8 +15844,8 @@ depending on the C definition of long)
@itemize *
@item
-"Any nonstandard integer types and the operators defined
-for them. See 3.5.4(26)."
+“Any nonstandard integer types and the operators defined
+for them. See 3.5.4(26).”
@end itemize
There are no nonstandard integer types.
@@ -15796,8 +15854,8 @@ There are no nonstandard integer types.
@itemize *
@item
-"Any nonstandard real types and the operators defined for
-them. See 3.5.6(8)."
+“Any nonstandard real types and the operators defined for
+them. See 3.5.6(8).”
@end itemize
There are no nonstandard real types.
@@ -15806,8 +15864,8 @@ There are no nonstandard real types.
@itemize *
@item
-"What combinations of requested decimal precision and range
-are supported for floating point types. See 3.5.7(7)."
+“What combinations of requested decimal precision and range
+are supported for floating point types. See 3.5.7(7).”
@end itemize
The precision and range are defined by the IEEE Standard for Floating-Point
@@ -15817,8 +15875,8 @@ Arithmetic (IEEE 754-2019).
@itemize *
@item
-"The predefined floating point types declared in
-@code{Standard}. See 3.5.7(16)."
+“The predefined floating point types declared in
+@code{Standard}. See 3.5.7(16).”
@end itemize
@@ -15878,7 +15936,7 @@ digits are requested, zeros are printed.
@itemize *
@item
-"The small of an ordinary fixed point type. See 3.5.9(8)."
+“The small of an ordinary fixed point type. See 3.5.9(8).”
@end itemize
The small is the largest power of two that does not exceed the delta.
@@ -15887,8 +15945,8 @@ The small is the largest power of two that does not exceed the delta.
@itemize *
@item
-"What combinations of small, range, and digits are
-supported for fixed point types. See 3.5.9(10)."
+“What combinations of small, range, and digits are
+supported for fixed point types. See 3.5.9(10).”
@end itemize
For an ordinary fixed point type, on 32-bit platforms, the small must lie in
@@ -15917,8 +15975,8 @@ small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.
@itemize *
@item
-"The result of @code{Tags.Expanded_Name} for types declared
-within an unnamed @emph{block_statement}. See 3.9(10)."
+“The result of @code{Tags.Expanded_Name} for types declared
+within an unnamed @emph{block_statement}. See 3.9(10).”
@end itemize
Block numbers of the form @code{B@emph{nnn}}, where @emph{nnn} is a
@@ -15928,7 +15986,7 @@ decimal integer are allocated.
@itemize *
@item
-"Implementation-defined attributes. See 4.1.4(12)."
+“Implementation-defined attributes. See 4.1.4(12).”
@end itemize
See @ref{8,,Implementation Defined Attributes}.
@@ -15937,7 +15995,7 @@ See @ref{8,,Implementation Defined Attributes}.
@itemize *
@item
-"Any implementation-defined time types. See 9.6(6)."
+“Any implementation-defined time types. See 9.6(6).”
@end itemize
There are no implementation-defined time types.
@@ -15946,7 +16004,7 @@ There are no implementation-defined time types.
@itemize *
@item
-"The time base associated with relative delays."
+“The time base associated with relative delays.”
@end itemize
See 9.6(20). The time base used is that provided by the C library
@@ -15956,8 +16014,8 @@ function @code{gettimeofday}.
@itemize *
@item
-"The time base of the type @code{Calendar.Time}. See
-9.6(23)."
+“The time base of the type @code{Calendar.Time}. See
+9.6(23).”
@end itemize
The time base used is that provided by the C library function
@@ -15967,8 +16025,8 @@ The time base used is that provided by the C library function
@itemize *
@item
-"The time zone used for package @code{Calendar}
-operations. See 9.6(24)."
+“The time zone used for package @code{Calendar}
+operations. See 9.6(24).”
@end itemize
The time zone used by package @code{Calendar} is the current system time zone
@@ -15979,8 +16037,8 @@ setting for local time, as accessed by the C library function
@itemize *
@item
-"Any limit on @emph{delay_until_statements} of
-@emph{select_statements}. See 9.6(29)."
+“Any limit on @emph{delay_until_statements} of
+@emph{select_statements}. See 9.6(29).”
@end itemize
There are no such limits.
@@ -15989,10 +16047,10 @@ There are no such limits.
@itemize *
@item
-"Whether or not two non-overlapping parts of a composite
+“Whether or not two non-overlapping parts of a composite
object are independently addressable, in the case where packing, record
layout, or @code{Component_Size} is specified for the object. See
-9.10(1)."
+9.10(1).”
@end itemize
Separate components are independently addressable if they do not share
@@ -16002,7 +16060,7 @@ overlapping storage units.
@itemize *
@item
-"The representation for a compilation. See 10.1(2)."
+“The representation for a compilation. See 10.1(2).”
@end itemize
A compilation is represented by a sequence of files presented to the
@@ -16012,8 +16070,8 @@ compiler in a single invocation of the @emph{gcc} command.
@itemize *
@item
-"Any restrictions on compilations that contain multiple
-compilation_units. See 10.1(4)."
+“Any restrictions on compilations that contain multiple
+compilation_units. See 10.1(4).”
@end itemize
No single file can contain more than one compilation unit, but any
@@ -16024,8 +16082,8 @@ compilation.
@itemize *
@item
-"The mechanisms for creating an environment and for adding
-and replacing compilation units. See 10.1.4(3)."
+“The mechanisms for creating an environment and for adding
+and replacing compilation units. See 10.1.4(3).”
@end itemize
See separate section on compilation model.
@@ -16034,8 +16092,8 @@ See separate section on compilation model.
@itemize *
@item
-"The manner of explicitly assigning library units to a
-partition. See 10.2(2)."
+“The manner of explicitly assigning library units to a
+partition. See 10.2(2).”
@end itemize
If a unit contains an Ada main program, then the Ada units for the partition
@@ -16055,15 +16113,15 @@ this case a list of units can be explicitly supplied to the binder for
inclusion in the partition (all units needed by these units will also
be included automatically). For full details on the use of these
options, refer to @emph{GNAT Make Program gnatmake} in the
-@cite{GNAT User's Guide}.
+@cite{GNAT User’s Guide}.
@itemize *
@item
-"The implementation-defined means, if any, of specifying
+“The implementation-defined means, if any, of specifying
which compilation units are needed by a given compilation unit. See
-10.2(2)."
+10.2(2).”
@end itemize
The units needed by a given compilation unit are as defined in
@@ -16075,8 +16133,8 @@ means for specifying needed units.
@itemize *
@item
-"The manner of designating the main subprogram of a
-partition. See 10.2(7)."
+“The manner of designating the main subprogram of a
+partition. See 10.2(7).”
@end itemize
The main program is designated by providing the name of the
@@ -16086,8 +16144,8 @@ corresponding @code{ALI} file as the input parameter to the binder.
@itemize *
@item
-"The order of elaboration of @emph{library_items}. See
-10.2(18)."
+“The order of elaboration of @emph{library_items}. See
+10.2(18).”
@end itemize
The first constraint on ordering is that it meets the requirements of
@@ -16103,8 +16161,8 @@ where a choice still remains.
@itemize *
@item
-"Parameter passing and function return for the main
-subprogram. See 10.2(21)."
+“Parameter passing and function return for the main
+subprogram. See 10.2(21).”
@end itemize
The main program has no parameters. It may be a procedure, or a function
@@ -16116,8 +16174,8 @@ may have been set by a call to @code{Ada.Command_Line.Set_Exit_Status}).
@itemize *
@item
-"The mechanisms for building and running partitions. See
-10.2(24)."
+“The mechanisms for building and running partitions. See
+10.2(24).”
@end itemize
GNAT itself supports programs with only a single partition. The GNATDIST
@@ -16130,8 +16188,8 @@ for details.
@itemize *
@item
-"The details of program execution, including program
-termination. See 10.2(25)."
+“The details of program execution, including program
+termination. See 10.2(25).”
@end itemize
See separate section on compilation model.
@@ -16140,8 +16198,8 @@ See separate section on compilation model.
@itemize *
@item
-"The semantics of any non-active partitions supported by the
-implementation. See 10.2(28)."
+“The semantics of any non-active partitions supported by the
+implementation. See 10.2(28).”
@end itemize
Passive partitions are supported on targets where shared memory is
@@ -16152,8 +16210,8 @@ further details.
@itemize *
@item
-"The information returned by @code{Exception_Message}. See
-11.4.1(10)."
+“The information returned by @code{Exception_Message}. See
+11.4.1(10).”
@end itemize
Exception message returns the null string unless a specific message has
@@ -16163,8 +16221,8 @@ been passed by the program.
@itemize *
@item
-"The result of @code{Exceptions.Exception_Name} for types
-declared within an unnamed @emph{block_statement}. See 11.4.1(12)."
+“The result of @code{Exceptions.Exception_Name} for types
+declared within an unnamed @emph{block_statement}. See 11.4.1(12).”
@end itemize
Blocks have implementation defined names of the form @code{B@emph{nnn}}
@@ -16174,8 +16232,8 @@ where @emph{nnn} is an integer.
@itemize *
@item
-"The information returned by
-@code{Exception_Information}. See 11.4.1(13)."
+“The information returned by
+@code{Exception_Information}. See 11.4.1(13).”
@end itemize
@code{Exception_Information} returns a string in the following format:
@@ -16212,7 +16270,7 @@ not making use of this field.
The Load address line, the Call stack traceback locations line and the
following values are present only if at least one traceback location was
recorded. The Load address indicates the address at which the main executable
-was loaded; this line may not be present if operating system hasn't relocated
+was loaded; this line may not be present if operating system hasn’t relocated
the main executable. The values are given in C style format, with lower case
letters for a-f, and only as many digits present as are necessary.
The line terminator sequence at the end of each line, including
@@ -16224,7 +16282,7 @@ the last line is a single @code{LF} character (@code{16#0A#}).
@itemize *
@item
-"Implementation-defined check names. See 11.5(27)."
+“Implementation-defined check names. See 11.5(27).”
@end itemize
The implementation defined check names include Alignment_Check,
@@ -16237,8 +16295,8 @@ Check_Name. See the description of pragma @code{Suppress} for full details.
@itemize *
@item
-"The interpretation of each aspect of representation. See
-13.1(20)."
+“The interpretation of each aspect of representation. See
+13.1(20).”
@end itemize
See separate section on data representations.
@@ -16247,8 +16305,8 @@ See separate section on data representations.
@itemize *
@item
-"Any restrictions placed upon representation items. See
-13.1(20)."
+“Any restrictions placed upon representation items. See
+13.1(20).”
@end itemize
See separate section on data representations.
@@ -16257,8 +16315,8 @@ See separate section on data representations.
@itemize *
@item
-"The meaning of @code{Size} for indefinite subtypes. See
-13.3(48)."
+“The meaning of @code{Size} for indefinite subtypes. See
+13.3(48).”
@end itemize
Size for an indefinite subtype is the maximum possible size, except that
@@ -16269,8 +16327,8 @@ is the actual size.
@itemize *
@item
-"The default external representation for a type tag. See
-13.3(75)."
+“The default external representation for a type tag. See
+13.3(75).”
@end itemize
The default external representation for a type tag is the fully expanded
@@ -16280,8 +16338,8 @@ name of the type in upper case letters.
@itemize *
@item
-"What determines whether a compilation unit is the same in
-two different partitions. See 13.3(76)."
+“What determines whether a compilation unit is the same in
+two different partitions. See 13.3(76).”
@end itemize
A compilation unit is the same in two different partitions if and only
@@ -16291,7 +16349,7 @@ if it derives from the same source file.
@itemize *
@item
-"Implementation-defined components. See 13.5.1(15)."
+“Implementation-defined components. See 13.5.1(15).”
@end itemize
The only implementation defined component is the tag for a tagged type,
@@ -16301,8 +16359,8 @@ which contains a pointer to the dispatching table.
@itemize *
@item
-"If @code{Word_Size} = @code{Storage_Unit}, the default bit
-ordering. See 13.5.3(5)."
+“If @code{Word_Size} = @code{Storage_Unit}, the default bit
+ordering. See 13.5.3(5).”
@end itemize
@code{Word_Size} (32) is not the same as @code{Storage_Unit} (8) for this
@@ -16313,8 +16371,8 @@ bit ordering corresponds to the natural endianness of the target architecture.
@itemize *
@item
-"The contents of the visible part of package @code{System}
-and its language-defined children. See 13.7(2)."
+“The contents of the visible part of package @code{System}
+and its language-defined children. See 13.7(2).”
@end itemize
See the definition of these packages in files @code{system.ads} and
@@ -16330,9 +16388,9 @@ Max_Interrupt_Priority : constant Positive := Interrupt_Priority'Last;
@itemize *
@item
-"The contents of the visible part of package
+“The contents of the visible part of package
@code{System.Machine_Code}, and the meaning of
-@emph{code_statements}. See 13.8(7)."
+@emph{code_statements}. See 13.8(7).”
@end itemize
See the definition and documentation in file @code{s-maccod.ads}.
@@ -16341,7 +16399,7 @@ See the definition and documentation in file @code{s-maccod.ads}.
@itemize *
@item
-"The effect of unchecked conversion. See 13.9(11)."
+“The effect of unchecked conversion. See 13.9(11).”
@end itemize
Unchecked conversion between types of the same size
@@ -16362,8 +16420,8 @@ made with appropriate alignment
@itemize *
@item
-"The semantics of operations on invalid representations.
-See 13.9.2(10-11)."
+“The semantics of operations on invalid representations.
+See 13.9.2(10-11).”
@end itemize
For assignments and other operations where the use of invalid values cannot
@@ -16391,8 +16449,8 @@ on the simple assignment of the invalid negative value from Y to Z.
@itemize *
@item
-"The manner of choosing a storage pool for an access type
-when @code{Storage_Pool} is not specified for the type. See 13.11(17)."
+“The manner of choosing a storage pool for an access type
+when @code{Storage_Pool} is not specified for the type. See 13.11(17).”
@end itemize
There are 3 different standard pools used by the compiler when
@@ -16408,8 +16466,8 @@ default pools used.
@itemize *
@item
-"Whether or not the implementation provides user-accessible
-names for the standard pool type(s). See 13.11(17)."
+“Whether or not the implementation provides user-accessible
+names for the standard pool type(s). See 13.11(17).”
@end itemize
See documentation in the sources of the run time mentioned in the previous
@@ -16420,7 +16478,7 @@ these units.
@itemize *
@item
-"The meaning of @code{Storage_Size}. See 13.11(18)."
+“The meaning of @code{Storage_Size}. See 13.11(18).”
@end itemize
@code{Storage_Size} is measured in storage units, and refers to the
@@ -16431,8 +16489,8 @@ stack space for a task.
@itemize *
@item
-"Implementation-defined aspects of storage pools. See
-13.11(22)."
+“Implementation-defined aspects of storage pools. See
+13.11(22).”
@end itemize
See documentation in the sources of the run time mentioned in the
@@ -16443,8 +16501,8 @@ for details on GNAT-defined aspects of storage pools.
@itemize *
@item
-"The set of restrictions allowed in a pragma
-@code{Restrictions}. See 13.12(7)."
+“The set of restrictions allowed in a pragma
+@code{Restrictions}. See 13.12(7).”
@end itemize
See @ref{9,,Standard and Implementation Defined Restrictions}.
@@ -16453,8 +16511,8 @@ See @ref{9,,Standard and Implementation Defined Restrictions}.
@itemize *
@item
-"The consequences of violating limitations on
-@code{Restrictions} pragmas. See 13.12(9)."
+“The consequences of violating limitations on
+@code{Restrictions} pragmas. See 13.12(9).”
@end itemize
Restrictions that can be checked at compile time result in illegalities
@@ -16465,9 +16523,9 @@ restrictions.
@itemize *
@item
-"The representation used by the @code{Read} and
+“The representation used by the @code{Read} and
@code{Write} attributes of elementary types in terms of stream
-elements. See 13.13.2(9)."
+elements. See 13.13.2(9).”
@end itemize
The representation is the in-memory representation of the base type of
@@ -16478,8 +16536,8 @@ the type, using the number of bits corresponding to the
@itemize *
@item
-"The names and characteristics of the numeric subtypes
-declared in the visible part of package @code{Standard}. See A.1(3)."
+“The names and characteristics of the numeric subtypes
+declared in the visible part of package @code{Standard}. See A.1(3).”
@end itemize
See items describing the integer and floating-point types supported.
@@ -16488,20 +16546,20 @@ See items describing the integer and floating-point types supported.
@itemize *
@item
-"The string returned by @code{Character_Set_Version}.
-See A.3.5(3)."
+“The string returned by @code{Character_Set_Version}.
+See A.3.5(3).”
@end itemize
@code{Ada.Wide_Characters.Handling.Character_Set_Version} returns
-the string "Unicode 4.0", referring to version 4.0 of the
+the string “Unicode 4.0”, referring to version 4.0 of the
Unicode specification.
@itemize *
@item
-"The accuracy actually achieved by the elementary
-functions. See A.5.1(1)."
+“The accuracy actually achieved by the elementary
+functions. See A.5.1(1).”
@end itemize
The elementary functions correspond to the functions available in the C
@@ -16511,9 +16569,9 @@ library. Only fast math mode is implemented.
@itemize *
@item
-"The sign of a zero result from some of the operators or
+“The sign of a zero result from some of the operators or
functions in @code{Numerics.Generic_Elementary_Functions}, when
-@code{Float_Type'Signed_Zeros} is @code{True}. See A.5.1(46)."
+@code{Float_Type'Signed_Zeros} is @code{True}. See A.5.1(46).”
@end itemize
The sign of zeroes follows the requirements of the IEEE 754 standard on
@@ -16523,8 +16581,8 @@ floating-point.
@itemize *
@item
-"The value of
-@code{Numerics.Float_Random.Max_Image_Width}. See A.5.2(27)."
+“The value of
+@code{Numerics.Float_Random.Max_Image_Width}. See A.5.2(27).”
@end itemize
Maximum image width is 6864, see library file @code{s-rannum.ads}.
@@ -16533,8 +16591,8 @@ Maximum image width is 6864, see library file @code{s-rannum.ads}.
@itemize *
@item
-"The value of
-@code{Numerics.Discrete_Random.Max_Image_Width}. See A.5.2(27)."
+“The value of
+@code{Numerics.Discrete_Random.Max_Image_Width}. See A.5.2(27).”
@end itemize
Maximum image width is 6864, see library file @code{s-rannum.ads}.
@@ -16543,8 +16601,8 @@ Maximum image width is 6864, see library file @code{s-rannum.ads}.
@itemize *
@item
-"The algorithms for random number generation. See
-A.5.2(32)."
+“The algorithms for random number generation. See
+A.5.2(32).”
@end itemize
The algorithm is the Mersenne Twister, as documented in the source file
@@ -16555,8 +16613,8 @@ The algorithm is the Mersenne Twister, as documented in the source file
@itemize *
@item
-"The string representation of a random number generator's
-state. See A.5.2(38)."
+“The string representation of a random number generator’s
+state. See A.5.2(38).”
@end itemize
The value returned by the Image function is the concatenation of
@@ -16567,9 +16625,9 @@ of the state vector.
@itemize *
@item
-"The minimum time interval between calls to the
+“The minimum time interval between calls to the
time-dependent Reset procedure that are guaranteed to initiate different
-random number sequences. See A.5.2(45)."
+random number sequences. See A.5.2(45).”
@end itemize
The minimum period between reset calls to guarantee distinct series of
@@ -16579,10 +16637,10 @@ random numbers is one microsecond.
@itemize *
@item
-"The values of the @code{Model_Mantissa},
+“The values of the @code{Model_Mantissa},
@code{Model_Emin}, @code{Model_Epsilon}, @code{Model},
@code{Safe_First}, and @code{Safe_Last} attributes, if the Numerics
-Annex is not supported. See A.5.3(72)."
+Annex is not supported. See A.5.3(72).”
@end itemize
Run the compiler with @emph{-gnatS} to produce a listing of package
@@ -16592,8 +16650,8 @@ Run the compiler with @emph{-gnatS} to produce a listing of package
@itemize *
@item
-"Any implementation-defined characteristics of the
-input-output packages. See A.7(14)."
+“Any implementation-defined characteristics of the
+input-output packages. See A.7(14).”
@end itemize
There are no special implementation defined characteristics for these
@@ -16603,8 +16661,8 @@ packages.
@itemize *
@item
-"The value of @code{Buffer_Size} in @code{Storage_IO}. See
-A.9(10)."
+“The value of @code{Buffer_Size} in @code{Storage_IO}. See
+A.9(10).”
@end itemize
All type representations are contiguous, and the @code{Buffer_Size} is
@@ -16615,8 +16673,8 @@ boundary.
@itemize *
@item
-"External files for standard input, standard output, and
-standard error See A.10(5)."
+“External files for standard input, standard output, and
+standard error See A.10(5).”
@end itemize
These files are mapped onto the files provided by the C streams
@@ -16626,8 +16684,8 @@ libraries. See source file @code{i-cstrea.ads} for further details.
@itemize *
@item
-"The accuracy of the value produced by @code{Put}. See
-A.10.9(36)."
+“The accuracy of the value produced by @code{Put}. See
+A.10.9(36).”
@end itemize
If more digits are requested in the output than are represented by the
@@ -16638,8 +16696,8 @@ significant digit positions.
@itemize *
@item
-"The meaning of @code{Argument_Count}, @code{Argument}, and
-@code{Command_Name}. See A.15(1)."
+“The meaning of @code{Argument_Count}, @code{Argument}, and
+@code{Command_Name}. See A.15(1).”
@end itemize
These are mapped onto the @code{argv} and @code{argc} parameters of the
@@ -16649,8 +16707,8 @@ main program in the natural manner.
@itemize *
@item
-"The interpretation of the @code{Form} parameter in procedure
-@code{Create_Directory}. See A.16(56)."
+“The interpretation of the @code{Form} parameter in procedure
+@code{Create_Directory}. See A.16(56).”
@end itemize
The @code{Form} parameter is not used.
@@ -16659,8 +16717,8 @@ The @code{Form} parameter is not used.
@itemize *
@item
-"The interpretation of the @code{Form} parameter in procedure
-@code{Create_Path}. See A.16(60)."
+“The interpretation of the @code{Form} parameter in procedure
+@code{Create_Path}. See A.16(60).”
@end itemize
The @code{Form} parameter is not used.
@@ -16669,8 +16727,8 @@ The @code{Form} parameter is not used.
@itemize *
@item
-"The interpretation of the @code{Form} parameter in procedure
-@code{Copy_File}. See A.16(68)."
+“The interpretation of the @code{Form} parameter in procedure
+@code{Copy_File}. See A.16(68).”
@end itemize
The @code{Form} parameter is case-insensitive.
@@ -16681,8 +16739,8 @@ Two fields are recognized in the @code{Form} parameter:
*mode=<value>*
@end example
-<value> starts immediately after the character '=' and ends with the
-character immediately preceding the next comma (',') or with the last
+<value> starts immediately after the character ‘=’ and ends with the
+character immediately preceding the next comma (‘,’) or with the last
character of the parameter.
The only possible values for preserve= are:
@@ -16790,9 +16848,9 @@ Form => "mode=internal, preserve=timestamps"
@itemize *
@item
-"The interpretation of the @code{Pattern} parameter, when not the null string,
+“The interpretation of the @code{Pattern} parameter, when not the null string,
in the @code{Start_Search} and @code{Search} procedures.
-See A.16(104) and A.16(112)."
+See A.16(104) and A.16(112).”
@end itemize
When the @code{Pattern} parameter is not the null string, it is interpreted
@@ -16805,7 +16863,7 @@ See @ref{25a,,GNAT.Regexp (g-regexp.ads)}.
@itemize *
@item
-"Implementation-defined convention names. See B.1(11)."
+“Implementation-defined convention names. See B.1(11).”
@end itemize
The following convention names are supported
@@ -16988,7 +17046,7 @@ use of such other names results in a warning.
@itemize *
@item
-"The meaning of link names. See B.1(36)."
+“The meaning of link names. See B.1(36).”
@end itemize
Link names are the actual names used by the linker.
@@ -16997,9 +17055,9 @@ Link names are the actual names used by the linker.
@itemize *
@item
-"The manner of choosing link names when neither the link
+“The manner of choosing link names when neither the link
name nor the address of an imported or exported entity is specified. See
-B.1(36)."
+B.1(36).”
@end itemize
The default linker name is that which would be assigned by the relevant
@@ -17010,7 +17068,7 @@ letters.
@itemize *
@item
-"The effect of pragma @code{Linker_Options}. See B.1(37)."
+“The effect of pragma @code{Linker_Options}. See B.1(37).”
@end itemize
The string passed to @code{Linker_Options} is presented uninterpreted as
@@ -17031,8 +17089,8 @@ from the corresponding package spec.
@itemize *
@item
-"The contents of the visible part of package
-@code{Interfaces} and its language-defined descendants. See B.2(1)."
+“The contents of the visible part of package
+@code{Interfaces} and its language-defined descendants. See B.2(1).”
@end itemize
See files with prefix @code{i-} in the distributed library.
@@ -17041,9 +17099,9 @@ See files with prefix @code{i-} in the distributed library.
@itemize *
@item
-"Implementation-defined children of package
+“Implementation-defined children of package
@code{Interfaces}. The contents of the visible part of package
-@code{Interfaces}. See B.2(11)."
+@code{Interfaces}. See B.2(11).”
@end itemize
See files with prefix @code{i-} in the distributed library.
@@ -17052,11 +17110,11 @@ See files with prefix @code{i-} in the distributed library.
@itemize *
@item
-"The types @code{Floating}, @code{Long_Floating},
+“The types @code{Floating}, @code{Long_Floating},
@code{Binary}, @code{Long_Binary}, @code{Decimal_ Element}, and
@code{COBOL_Character}; and the initialization of the variables
@code{Ada_To_COBOL} and @code{COBOL_To_Ada}, in
-@code{Interfaces.COBOL}. See B.4(50)."
+@code{Interfaces.COBOL}. See B.4(50).”
@end itemize
@@ -17126,7 +17184,7 @@ For initialization, see the file @code{i-cobol.ads} in the distributed library.
@itemize *
@item
-"Support for access to machine instructions. See C.1(1)."
+“Support for access to machine instructions. See C.1(1).”
@end itemize
See documentation in file @code{s-maccod.ads} in the distributed library.
@@ -17135,8 +17193,8 @@ See documentation in file @code{s-maccod.ads} in the distributed library.
@itemize *
@item
-"Implementation-defined aspects of access to machine
-operations. See C.1(9)."
+“Implementation-defined aspects of access to machine
+operations. See C.1(9).”
@end itemize
See documentation in file @code{s-maccod.ads} in the distributed library.
@@ -17145,7 +17203,7 @@ See documentation in file @code{s-maccod.ads} in the distributed library.
@itemize *
@item
-"Implementation-defined aspects of interrupts. See C.3(2)."
+“Implementation-defined aspects of interrupts. See C.3(2).”
@end itemize
Interrupts are mapped to signals or conditions as appropriate. See
@@ -17157,8 +17215,8 @@ on the interrupts supported on a particular target.
@itemize *
@item
-"Implementation-defined aspects of pre-elaboration. See
-C.4(13)."
+“Implementation-defined aspects of pre-elaboration. See
+C.4(13).”
@end itemize
GNAT does not permit a partition to be restarted without reloading,
@@ -17168,7 +17226,7 @@ except under control of the debugger.
@itemize *
@item
-"The semantics of pragma @code{Discard_Names}. See C.5(7)."
+“The semantics of pragma @code{Discard_Names}. See C.5(7).”
@end itemize
Pragma @code{Discard_Names} causes names of enumeration literals to
@@ -17185,8 +17243,8 @@ level.
@itemize *
@item
-"The result of the @code{Task_Identification.Image}
-attribute. See C.7.1(7)."
+“The result of the @code{Task_Identification.Image}
+attribute. See C.7.1(7).”
@end itemize
The result of this attribute is a string that identifies
@@ -17217,8 +17275,8 @@ virtual address of the control block of the task.
@itemize *
@item
-"The value of @code{Current_Task} when in a protected entry
-or interrupt handler. See C.7.1(17)."
+“The value of @code{Current_Task} when in a protected entry
+or interrupt handler. See C.7.1(17).”
@end itemize
Protected entries or interrupt handlers can be executed by any
@@ -17228,8 +17286,8 @@ convenient thread, so the value of @code{Current_Task} is undefined.
@itemize *
@item
-"The effect of calling @code{Current_Task} from an entry
-body or interrupt handler. See C.7.1(19)."
+“The effect of calling @code{Current_Task} from an entry
+body or interrupt handler. See C.7.1(19).”
@end itemize
When GNAT can determine statically that @code{Current_Task} is called directly in
@@ -17242,8 +17300,8 @@ currently executing the code.
@itemize *
@item
-"Implementation-defined aspects of
-@code{Task_Attributes}. See C.7.2(19)."
+“Implementation-defined aspects of
+@code{Task_Attributes}. See C.7.2(19).”
@end itemize
There are no implementation-defined aspects of @code{Task_Attributes}.
@@ -17252,7 +17310,7 @@ There are no implementation-defined aspects of @code{Task_Attributes}.
@itemize *
@item
-"Values of all @code{Metrics}. See D(2)."
+“Values of all @code{Metrics}. See D(2).”
@end itemize
The metrics information for GNAT depends on the performance of the
@@ -17268,8 +17326,8 @@ the required metrics.
@itemize *
@item
-"The declarations of @code{Any_Priority} and
-@code{Priority}. See D.1(11)."
+“The declarations of @code{Any_Priority} and
+@code{Priority}. See D.1(11).”
@end itemize
See declarations in file @code{system.ads}.
@@ -17278,7 +17336,7 @@ See declarations in file @code{system.ads}.
@itemize *
@item
-"Implementation-defined execution resources. See D.1(15)."
+“Implementation-defined execution resources. See D.1(15).”
@end itemize
There are no implementation-defined execution resources.
@@ -17287,8 +17345,8 @@ There are no implementation-defined execution resources.
@itemize *
@item
-"Whether, on a multiprocessor, a task that is waiting for
-access to a protected object keeps its processor busy. See D.2.1(3)."
+“Whether, on a multiprocessor, a task that is waiting for
+access to a protected object keeps its processor busy. See D.2.1(3).”
@end itemize
On a multi-processor, a task that is waiting for access to a protected
@@ -17298,8 +17356,8 @@ object does not keep its processor busy.
@itemize *
@item
-"The affect of implementation defined execution resources
-on task dispatching. See D.2.1(9)."
+“The affect of implementation defined execution resources
+on task dispatching. See D.2.1(9).”
@end itemize
Tasks map to threads in the threads package used by GNAT. Where possible
@@ -17310,8 +17368,8 @@ underlying operating system.
@itemize *
@item
-"Implementation-defined @emph{policy_identifiers} allowed
-in a pragma @code{Task_Dispatching_Policy}. See D.2.2(3)."
+“Implementation-defined @emph{policy_identifiers} allowed
+in a pragma @code{Task_Dispatching_Policy}. See D.2.2(3).”
@end itemize
There are no implementation-defined policy-identifiers allowed in this
@@ -17321,8 +17379,8 @@ pragma.
@itemize *
@item
-"Implementation-defined aspects of priority inversion. See
-D.2.2(16)."
+“Implementation-defined aspects of priority inversion. See
+D.2.2(16).”
@end itemize
Execution of a task cannot be preempted by the implementation processing
@@ -17332,7 +17390,7 @@ of delay expirations for lower priority tasks.
@itemize *
@item
-"Implementation-defined task dispatching. See D.2.2(18)."
+“Implementation-defined task dispatching. See D.2.2(18).”
@end itemize
The policy is the same as that of the underlying threads implementation.
@@ -17341,8 +17399,8 @@ The policy is the same as that of the underlying threads implementation.
@itemize *
@item
-"Implementation-defined @emph{policy_identifiers} allowed
-in a pragma @code{Locking_Policy}. See D.3(4)."
+“Implementation-defined @emph{policy_identifiers} allowed
+in a pragma @code{Locking_Policy}. See D.3(4).”
@end itemize
The two implementation defined policies permitted in GNAT are
@@ -17359,7 +17417,7 @@ concurrently.
@itemize *
@item
-"Default ceiling priorities. See D.3(10)."
+“Default ceiling priorities. See D.3(10).”
@end itemize
The ceiling priority of protected objects of the type
@@ -17370,8 +17428,8 @@ Reference Manual D.3(10),
@itemize *
@item
-"The ceiling of any protected object used internally by
-the implementation. See D.3(16)."
+“The ceiling of any protected object used internally by
+the implementation. See D.3(16).”
@end itemize
The ceiling priority of internal protected objects is
@@ -17381,7 +17439,7 @@ The ceiling priority of internal protected objects is
@itemize *
@item
-"Implementation-defined queuing policies. See D.4(1)."
+“Implementation-defined queuing policies. See D.4(1).”
@end itemize
There are no implementation-defined queuing policies.
@@ -17390,9 +17448,9 @@ There are no implementation-defined queuing policies.
@itemize *
@item
-"On a multiprocessor, any conditions that cause the
+“On a multiprocessor, any conditions that cause the
completion of an aborted construct to be delayed later than what is
-specified for a single processor. See D.6(3)."
+specified for a single processor. See D.6(3).”
@end itemize
The semantics for abort on a multi-processor is the same as on a single
@@ -17402,8 +17460,8 @@ processor, there are no further delays.
@itemize *
@item
-"Any operations that implicitly require heap storage
-allocation. See D.7(8)."
+“Any operations that implicitly require heap storage
+allocation. See D.7(8).”
@end itemize
The only operation that implicitly requires heap storage allocation is
@@ -17413,8 +17471,8 @@ task creation.
@itemize *
@item
-"What happens when a task terminates in the presence of
-pragma @code{No_Task_Termination}. See D.7(15)."
+“What happens when a task terminates in the presence of
+pragma @code{No_Task_Termination}. See D.7(15).”
@end itemize
Execution is erroneous in that case.
@@ -17423,8 +17481,8 @@ Execution is erroneous in that case.
@itemize *
@item
-"Implementation-defined aspects of pragma
-@code{Restrictions}. See D.7(20)."
+“Implementation-defined aspects of pragma
+@code{Restrictions}. See D.7(20).”
@end itemize
There are no such implementation-defined aspects.
@@ -17433,8 +17491,8 @@ There are no such implementation-defined aspects.
@itemize *
@item
-"Implementation-defined aspects of package
-@code{Real_Time}. See D.8(17)."
+“Implementation-defined aspects of package
+@code{Real_Time}. See D.8(17).”
@end itemize
There are no implementation defined aspects of package @code{Real_Time}.
@@ -17443,8 +17501,8 @@ There are no implementation defined aspects of package @code{Real_Time}.
@itemize *
@item
-"Implementation-defined aspects of
-@emph{delay_statements}. See D.9(8)."
+“Implementation-defined aspects of
+@emph{delay_statements}. See D.9(8).”
@end itemize
Any difference greater than one microsecond will cause the task to be
@@ -17454,8 +17512,8 @@ delayed (see D.9(7)).
@itemize *
@item
-"The upper bound on the duration of interrupt blocking
-caused by the implementation. See D.12(5)."
+“The upper bound on the duration of interrupt blocking
+caused by the implementation. See D.12(5).”
@end itemize
The upper bound is determined by the underlying operating system. In
@@ -17465,8 +17523,8 @@ no cases is it more than 10 milliseconds.
@itemize *
@item
-"The means for creating and executing distributed
-programs. See E(5)."
+“The means for creating and executing distributed
+programs. See E(5).”
@end itemize
The GLADE package provides a utility GNATDIST for creating and executing
@@ -17476,8 +17534,8 @@ distributed programs. See the GLADE reference manual for further details.
@itemize *
@item
-"Any events that can result in a partition becoming
-inaccessible. See E.1(7)."
+“Any events that can result in a partition becoming
+inaccessible. See E.1(7).”
@end itemize
See the GLADE reference manual for full details on such events.
@@ -17486,9 +17544,9 @@ See the GLADE reference manual for full details on such events.
@itemize *
@item
-"The scheduling policies, treatment of priorities, and
+“The scheduling policies, treatment of priorities, and
management of shared resources between partitions in certain cases. See
-E.1(11)."
+E.1(11).”
@end itemize
See the GLADE reference manual for full details on these aspects of
@@ -17498,8 +17556,8 @@ multi-partition execution.
@itemize *
@item
-"Events that cause the version of a compilation unit to
-change. See E.3(5)."
+“Events that cause the version of a compilation unit to
+change. See E.3(5).”
@end itemize
Editing the source file of a compilation unit, or the source files of
@@ -17512,8 +17570,8 @@ comments.
@itemize *
@item
-"Whether the execution of the remote subprogram is
-immediately aborted as a result of cancellation. See E.4(13)."
+“Whether the execution of the remote subprogram is
+immediately aborted as a result of cancellation. See E.4(13).”
@end itemize
See the GLADE reference manual for details on the effect of abort in
@@ -17523,7 +17581,7 @@ a distributed application.
@itemize *
@item
-"Implementation-defined aspects of the PCS. See E.5(25)."
+“Implementation-defined aspects of the PCS. See E.5(25).”
@end itemize
See the GLADE reference manual for a full description of all implementation
@@ -17533,8 +17591,8 @@ defined aspects of the PCS.
@itemize *
@item
-"Implementation-defined interfaces in the PCS. See
-E.5(26)."
+“Implementation-defined interfaces in the PCS. See
+E.5(26).”
@end itemize
See the GLADE reference manual for a full description of all
@@ -17544,8 +17602,8 @@ implementation defined interfaces.
@itemize *
@item
-"The values of named numbers in the package
-@code{Decimal}. See F.2(7)."
+“The values of named numbers in the package
+@code{Decimal}. See F.2(7).”
@end itemize
@@ -17605,8 +17663,8 @@ Value
@itemize *
@item
-"The value of @code{Max_Picture_Length} in the package
-@code{Text_IO.Editing}. See F.3.3(16)."
+“The value of @code{Max_Picture_Length} in the package
+@code{Text_IO.Editing}. See F.3.3(16).”
@end itemize
64
@@ -17615,8 +17673,8 @@ Value
@itemize *
@item
-"The value of @code{Max_Picture_Length} in the package
-@code{Wide_Text_IO.Editing}. See F.3.4(5)."
+“The value of @code{Max_Picture_Length} in the package
+@code{Wide_Text_IO.Editing}. See F.3.4(5).”
@end itemize
64
@@ -17625,8 +17683,8 @@ Value
@itemize *
@item
-"The accuracy actually achieved by the complex elementary
-functions and by other complex arithmetic operations. See G.1(1)."
+“The accuracy actually achieved by the complex elementary
+functions and by other complex arithmetic operations. See G.1(1).”
@end itemize
Standard library functions are used for the complex arithmetic
@@ -17636,9 +17694,9 @@ operations. Only fast math mode is currently supported.
@itemize *
@item
-"The sign of a zero result (or a component thereof) from
+“The sign of a zero result (or a component thereof) from
any operator or function in @code{Numerics.Generic_Complex_Types}, when
-@code{Real'Signed_Zeros} is True. See G.1.1(53)."
+@code{Real'Signed_Zeros} is True. See G.1.1(53).”
@end itemize
The signs of zero values are as recommended by the relevant
@@ -17648,10 +17706,10 @@ implementation advice.
@itemize *
@item
-"The sign of a zero result (or a component thereof) from
+“The sign of a zero result (or a component thereof) from
any operator or function in
@code{Numerics.Generic_Complex_Elementary_Functions}, when
-@code{Real'Signed_Zeros} is @code{True}. See G.1.2(45)."
+@code{Real'Signed_Zeros} is @code{True}. See G.1.2(45).”
@end itemize
The signs of zero values are as recommended by the relevant
@@ -17661,8 +17719,8 @@ implementation advice.
@itemize *
@item
-"Whether the strict mode or the relaxed mode is the
-default. See G.2(2)."
+“Whether the strict mode or the relaxed mode is the
+default. See G.2(2).”
@end itemize
The strict mode is the default. There is no separate relaxed mode. GNAT
@@ -17672,8 +17730,8 @@ provides a highly efficient implementation of strict mode.
@itemize *
@item
-"The result interval in certain cases of fixed-to-float
-conversion. See G.2.1(10)."
+“The result interval in certain cases of fixed-to-float
+conversion. See G.2.1(10).”
@end itemize
For cases where the result interval is implementation dependent, the
@@ -17684,9 +17742,9 @@ floating-point format.
@itemize *
@item
-"The result of a floating point arithmetic operation in
+“The result of a floating point arithmetic operation in
overflow situations, when the @code{Machine_Overflows} attribute of the
-result type is @code{False}. See G.2.1(13)."
+result type is @code{False}. See G.2.1(13).”
@end itemize
Infinite and NaN values are produced as dictated by the IEEE
@@ -17701,9 +17759,9 @@ properly generated.
@itemize *
@item
-"The result interval for division (or exponentiation by a
+“The result interval for division (or exponentiation by a
negative exponent), when the floating point hardware implements division
-as multiplication by a reciprocal. See G.2.1(16)."
+as multiplication by a reciprocal. See G.2.1(16).”
@end itemize
Not relevant, division is IEEE exact.
@@ -17712,9 +17770,9 @@ Not relevant, division is IEEE exact.
@itemize *
@item
-"The definition of close result set, which determines the
+“The definition of close result set, which determines the
accuracy of certain fixed point multiplications and divisions. See
-G.2.3(5)."
+G.2.3(5).”
@end itemize
Operations in the close result set are performed using IEEE long format
@@ -17726,9 +17784,9 @@ is converted to the target type.
@itemize *
@item
-"Conditions on a @emph{universal_real} operand of a fixed
+“Conditions on a @emph{universal_real} operand of a fixed
point multiplication or division for which the result shall be in the
-perfect result set. See G.2.3(22)."
+perfect result set. See G.2.3(22).”
@end itemize
The result is only defined to be in the perfect result set if the result
@@ -17739,9 +17797,9 @@ representable in 64 bits.
@itemize *
@item
-"The result of a fixed point arithmetic operation in
+“The result of a fixed point arithmetic operation in
overflow situations, when the @code{Machine_Overflows} attribute of the
-result type is @code{False}. See G.2.3(27)."
+result type is @code{False}. See G.2.3(27).”
@end itemize
Not relevant, @code{Machine_Overflows} is @code{True} for fixed-point
@@ -17751,9 +17809,9 @@ types.
@itemize *
@item
-"The result of an elementary function reference in
+“The result of an elementary function reference in
overflow situations, when the @code{Machine_Overflows} attribute of the
-result type is @code{False}. See G.2.4(4)."
+result type is @code{False}. See G.2.4(4).”
@end itemize
IEEE infinite and Nan values are produced as appropriate.
@@ -17762,10 +17820,10 @@ IEEE infinite and Nan values are produced as appropriate.
@itemize *
@item
-"The value of the angle threshold, within which certain
+“The value of the angle threshold, within which certain
elementary functions, complex arithmetic operations, and complex
elementary functions yield results conforming to a maximum relative
-error bound. See G.2.4(10)."
+error bound. See G.2.4(10).”
@end itemize
Information on this subject is not yet available.
@@ -17774,8 +17832,8 @@ Information on this subject is not yet available.
@itemize *
@item
-"The accuracy of certain elementary functions for
-parameters beyond the angle threshold. See G.2.4(10)."
+“The accuracy of certain elementary functions for
+parameters beyond the angle threshold. See G.2.4(10).”
@end itemize
Information on this subject is not yet available.
@@ -17784,10 +17842,10 @@ Information on this subject is not yet available.
@itemize *
@item
-"The result of a complex arithmetic operation or complex
+“The result of a complex arithmetic operation or complex
elementary function reference in overflow situations, when the
@code{Machine_Overflows} attribute of the corresponding real type is
-@code{False}. See G.2.6(5)."
+@code{False}. See G.2.6(5).”
@end itemize
IEEE infinite and Nan values are produced as appropriate.
@@ -17796,9 +17854,9 @@ IEEE infinite and Nan values are produced as appropriate.
@itemize *
@item
-"The accuracy of certain complex arithmetic operations and
+“The accuracy of certain complex arithmetic operations and
certain complex elementary functions for parameters (or components
-thereof) beyond the angle threshold. See G.2.6(8)."
+thereof) beyond the angle threshold. See G.2.6(8).”
@end itemize
Information on those subjects is not yet available.
@@ -17807,8 +17865,8 @@ Information on those subjects is not yet available.
@itemize *
@item
-"Information regarding bounded errors and erroneous
-execution. See H.2(1)."
+“Information regarding bounded errors and erroneous
+execution. See H.2(1).”
@end itemize
Information on this subject is not yet available.
@@ -17817,8 +17875,8 @@ Information on this subject is not yet available.
@itemize *
@item
-"Implementation-defined aspects of pragma
-@code{Inspection_Point}. See H.3.2(8)."
+“Implementation-defined aspects of pragma
+@code{Inspection_Point}. See H.3.2(8).”
@end itemize
Pragma @code{Inspection_Point} ensures that the variable is live and can
@@ -17828,8 +17886,8 @@ be examined by the debugger at the inspection point.
@itemize *
@item
-"Implementation-defined aspects of pragma
-@code{Restrictions}. See H.4(25)."
+“Implementation-defined aspects of pragma
+@code{Restrictions}. See H.4(25).”
@end itemize
There are no implementation-defined aspects of pragma @code{Restrictions}. The
@@ -17840,14 +17898,14 @@ generated code. Checks must suppressed by use of pragma @code{Suppress}.
@itemize *
@item
-"Any restrictions on pragma @code{Restrictions}. See
-H.4(27)."
+“Any restrictions on pragma @code{Restrictions}. See
+H.4(27).”
@end itemize
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{25b}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25c}
+@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{25b}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25c}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}
@chapter Intrinsic Subprograms
@@ -17910,13 +17968,13 @@ function "+" (X1 : Int1; X2 : Int2) return Int2;
pragma Import (Intrinsic, "+");
@end example
-This declaration would permit 'mixed mode' arithmetic on items
+This declaration would permit ‘mixed mode’ arithmetic on items
of the differing types @code{Int1} and @code{Int2}.
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{25f}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{260}
+@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{25f}@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{260}
@section Compilation_ISO_Date
@@ -17954,7 +18012,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{265}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{266}
+@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{265}@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{266}
@section Enclosing_Entity
@@ -17968,7 +18026,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{267}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{268}
+@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{267}@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{268}
@section Exception_Information
@@ -18010,7 +18068,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{26d}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26e}
+@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26d}@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{26e}
@section File
@@ -18038,7 +18096,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{271}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{272}
+@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{271}@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{272}
@section Shifts and Rotates
@@ -18066,7 +18124,7 @@ with Import, Convention => Intrinsic;
The function name must be one of
Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, or
-Rotate_Right. T must be an integer type. T'Size must be
+Rotate_Right. T must be an integer type. T’Size must be
8, 16, 32 or 64 bits; if T is modular, the modulus
must be 2**8, 2**16, 2**32 or 2**64.
The result type must be the same as the type of @code{Value}.
@@ -18075,13 +18133,13 @@ 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. For signed types
+corresponding pragma Import’s for all five shift functions. For signed types
the semantics of these operators is to interpret the bitwise result of the
corresponding operator for modular type. In particular, shifting a negative
number may change its sign bit to positive.
@node Source_Location,,Shifts and Rotates,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{273}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{274}
+@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{273}@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{274}
@section Source_Location
@@ -18095,7 +18153,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{275}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{276}
+@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{275}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{276}@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}
@chapter Representation Clauses and Pragmas
@@ -18141,7 +18199,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{277}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{278}
+@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{277}@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{278}
@section Alignment Clauses
@@ -18316,10 +18374,10 @@ in accordance with the specific Implementation Advice in RM 13.3(43):
@quotation
-"A @code{Size} clause should be supported for an object if the specified
-@code{Size} is at least as large as its subtype's @code{Size}, and corresponds
-to a size in storage elements that is a multiple of the object's
-@code{Alignment} (if the @code{Alignment} is nonzero)."
+“A @code{Size} clause should be supported for an object if the specified
+@code{Size} is at least as large as its subtype’s @code{Size}, and corresponds
+to a size in storage elements that is a multiple of the object’s
+@code{Alignment} (if the @code{Alignment} is nonzero).”
@end quotation
An explicit size clause may be used to override the default size by
@@ -18349,7 +18407,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{27b}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27c}
+@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27b}@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{27c}
@section Storage_Size Clauses
@@ -18532,7 +18590,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{27f}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{280}
+@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{27f}@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{280}
@section Biased Representation
@@ -18617,7 +18675,7 @@ objects of the type respectively.
The @code{Object_Size} is used for determining the default size of
objects and components. This size value can be referred to using the
-@code{Object_Size} attribute. The phrase 'is used' here means that it is
+@code{Object_Size} attribute. The phrase ‘is used’ here means that it is
the basis of the determination of the size. The backend is free to
pad this up if necessary for efficiency, e.g., an 8-bit stand-alone
character might be stored in 32 bits on a machine with no efficient
@@ -18669,8 +18727,8 @@ only if negative values are possible).
@item
If a subtype statically matches the first subtype of a given type, then it has
by default the same @code{Value_Size} as the first subtype. This is a
-consequence of RM 13.1(14): "if two subtypes statically match,
-then their subtype-specific aspects are the same".)
+consequence of RM 13.1(14): “if two subtypes statically match,
+then their subtype-specific aspects are the same”.)
@item
All other subtypes have a @code{Value_Size} corresponding to the minimum
@@ -18803,7 +18861,7 @@ Value_Size
@end multitable
-Note: the entries marked '*' are not actually specified by the Ada
+Note: the entries marked ‘*’ are not actually specified by the Ada
Reference Manual, which has nothing to say about size in the dynamic
case. What GNAT does is to allocate sufficient bits to accommodate any
possible dynamic values for the bounds at run-time.
@@ -18849,7 +18907,7 @@ the alignment requirement for objects of the record type. The X
component will require four-byte alignment because that is what type
Integer requires, whereas the Y component, a Character, will only
require 1-byte alignment. Since the alignment required for X is the
-greatest of all the components' alignments, that is the alignment
+greatest of all the components’ alignments, that is the alignment
required for the enclosing record type, i.e., 4 bytes or 32 bits. As
indicated above, the actual object size must be rounded up so that it is
a multiple of the alignment value. Therefore, 40 bits rounded up to the
@@ -18886,7 +18944,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{283}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{284}
+@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{283}@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{284}
@section Component_Size Clauses
@@ -19040,7 +19098,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{287}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{288}
+@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{287}@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{288}
@section Effect of Bit_Order on Byte Ordering
@@ -19059,8 +19117,8 @@ Reference Manual:
@quotation
-"2 A bit ordering is a method of interpreting the meaning of
-the storage place attributes."
+“2 A bit ordering is a method of interpreting the meaning of
+the storage place attributes.”
@end quotation
To understand the precise definition of storage place attributes in
@@ -19068,11 +19126,11 @@ this context, we visit section 13.5.1 of the manual:
@quotation
-"13 A record_representation_clause (without the mod_clause)
+“13 A record_representation_clause (without the mod_clause)
specifies the layout. The storage place attributes (see 13.5.2)
are taken from the values of the position, first_bit, and last_bit
expressions after normalizing those values so that first_bit is
-less than Storage_Unit."
+less than Storage_Unit.”
@end quotation
The critical point here is that storage places are taken from
@@ -19082,14 +19140,14 @@ is described in the later part of the 13.5.3 paragraph:
@quotation
-"2 A bit ordering is a method of interpreting the meaning of
+“2 A bit ordering is a method of interpreting the meaning of
the storage place attributes. High_Order_First (known in the
-vernacular as 'big endian') means that the first bit of a
+vernacular as ‘big endian’) means that the first bit of a
storage element (bit 0) is the most significant bit (interpreting
the sequence of bits that represent a component as an unsigned
integer value). Low_Order_First (known in the vernacular as
-'little endian') means the opposite: the first bit is the
-least significant."
+‘little endian’) means the opposite: the first bit is the
+least significant.”
@end quotation
Note that the numbering is with respect to the bits of a storage
@@ -19103,7 +19161,7 @@ byte presented, which is the first (low addressed byte) of the two byte
record is called Master, and the second byte is called Slave.
The left most (most significant bit is called Control for each byte, and
-the remaining 7 bits are called V1, V2, ... V7, where V7 is the rightmost
+the remaining 7 bits are called V1, V2, … V7, where V7 is the rightmost
(least significant) bit.
On a big-endian machine, we can write the following representation clause
@@ -19297,7 +19355,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{289}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{28a}
+@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{289}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{28a}
@section Pragma Pack for Arrays
@@ -19417,7 +19475,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{28b}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28c}
+@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28b}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{28c}
@section Pragma Pack for Records
@@ -19586,7 +19644,7 @@ end record;
@geindex Handling of Records with Holes
-As a result of alignment considerations, records may contain "holes"
+As a result of alignment considerations, records may contain “holes”
or gaps which do not correspond to the data bits of any of the components.
Record representation clauses can also result in holes in records.
@@ -19699,7 +19757,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{293}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{294}
+@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{293}@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{294}
@section Address Clauses
@@ -19710,12 +19768,12 @@ as found in RM 13.1(22):
@quotation
-"An implementation need not support representation
+“An implementation need not support representation
items containing nonstatic expressions, except that
an implementation should support a representation item
for a given entity if each nonstatic expression in the
representation item is a name that statically denotes
-a constant declared before the entity."
+a constant declared before the entity.”
@end quotation
In practice this is applicable only to address clauses, since this is the
@@ -19726,9 +19784,9 @@ the AARM notes in sections 13.1 (22.a-22.h):
22.a Reason: This is to avoid the following sort of thing:
-22.b X : Integer := F(...);
-Y : Address := G(...);
-for X'Address use Y;
+22.b X : Integer := F(…);
+Y : Address := G(…);
+for X’Address use Y;
22.c In the above, we have to evaluate the
initialization expression for X before we
@@ -19738,11 +19796,11 @@ like an unreasonable implementation burden.
22.d The above code should instead be written
like this:
-22.e Y : constant Address := G(...);
-X : Integer := F(...);
-for X'Address use Y;
+22.e Y : constant Address := G(…);
+X : Integer := F(…);
+for X’Address use Y;
-22.f This allows the expression 'Y' to be safely
+22.f This allows the expression ‘Y’ to be safely
evaluated before X is created.
22.g The constant could be a formal parameter of mode in.
@@ -19789,7 +19847,7 @@ a component of a discriminated record.
As noted above in section 22.h, address values are typically nonstatic. In
particular the To_Address function, even if applied to a literal value, is
a nonstatic function call. To avoid this minor annoyance, GNAT provides
-the implementation defined attribute 'To_Address. The following two
+the implementation defined attribute ‘To_Address. The following two
expressions have identical values:
@geindex Attribute
@@ -19919,14 +19977,14 @@ implementation advice (RM 13.3(19)):
@quotation
-"19 If the Address of an object is specified, or it is imported
+“19 If the Address of an object is specified, or it is imported
or exported, then the implementation should not perform
-optimizations based on assumptions of no aliases."
+optimizations based on assumptions of no aliases.”
@end quotation
GNAT follows this recommendation, and goes further by also applying
this recommendation to the overlaid variable (@code{A} in the above example)
-in this case. This means that the overlay works "as expected", in that
+in this case. This means that the overlay works “as expected”, in that
a modification to one of the variables will affect the value of the other.
More generally, GNAT interprets this recommendation conservatively for
@@ -20086,7 +20144,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{297}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{298}
+@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{297}@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{298}
@section Effect of Convention on Representation
@@ -20183,7 +20241,7 @@ then the convention will apply to this anonymous type as well. This
seems to make sense since it is anomolous in any case to have a
different convention for an object and its type, and there is clearly
no way to explicitly specify a convention for an anonymous type, since
-it doesn't have a name to specify!
+it doesn’t have a name to specify!
Furthermore, we decide that if a convention is applied to a record type,
then this convention is inherited by any of its components that are of an
@@ -20240,7 +20298,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{29b}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29c}
+@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29b}@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{29c}
@section Determining the Representations chosen by GNAT
@@ -20392,7 +20450,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{29d}@anchor{gnat_rm/standard_library_routines id1}@anchor{29e}
+@anchor{gnat_rm/standard_library_routines doc}@anchor{29d}@anchor{gnat_rm/standard_library_routines id1}@anchor{29e}@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}
@chapter Standard Library Routines
@@ -20567,7 +20625,7 @@ operations, which is not implemented in GNAT.
This package provides constants describing the range of decimal numbers
implemented, and also a decimal divide routine (analogous to the COBOL
-verb DIVIDE ... GIVING ... REMAINDER ...)
+verb DIVIDE … GIVING … REMAINDER …)
@item @code{Ada.Direct_IO} @emph{(A.8.4)}
@@ -20615,7 +20673,7 @@ all targets (see package spec for details).
Not implemented in GNAT.
-@item @code{Ada.Execution_Time.Timers} @emph{(D.14.1)'}
+@item @code{Ada.Execution_Time.Timers} @emph{(D.14.1)’}
Not implemented in GNAT.
@@ -21216,7 +21274,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{29f}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{29f}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a0}@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}
@chapter The Implementation of Standard I/O
@@ -21268,7 +21326,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{2a1}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a1}@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a2}
@section Standard I/O Packages
@@ -21385,7 +21443,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{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a8}
@section Sequential_IO
@@ -21551,7 +21609,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{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ae}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2ae}
@subsection Reading and Writing Non-Regular Files
@@ -21592,7 +21650,7 @@ above they will not be treated as page marks on input if the output is
piped to another Ada program.
Another important discrepancy when reading non-regular files is that the end
-of file indication is not 'sticky'. If an end of file is entered, e.g., by
+of file indication is not ‘sticky’. If an end of file is entered, e.g., by
pressing the @code{EOT} key,
then end of file
is signaled once (i.e., the test @code{End_Of_File}
@@ -21664,7 +21722,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{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b6}
@subsection Text_IO Facilities for Unbounded Strings
@@ -21712,7 +21770,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{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b8}
@section Wide_Text_IO
@@ -21915,11 +21973,11 @@ as UTF-8 will be used for text input output.
If brackets notation is used, then any occurrence of a left bracket
in the input file which is not the start of a valid wide character
sequence will cause Constraint_Error to be raised. It is possible to
-encode a left bracket as ["5B"] and Wide_Text_IO and Wide_Wide_Text_IO
+encode a left bracket as [“5B”] and Wide_Text_IO and Wide_Wide_Text_IO
input will interpret this as a left bracket.
However, when a left bracket is output, it will be output as a left bracket
-and not as ["5B"]. We make this decision because for normal use of
+and not as [“5B”]. We make this decision because for normal use of
Wide_Text_IO for outputting messages, it is unpleasant to clobber left
brackets. For example, if we write:
@@ -21939,7 +21997,7 @@ Start of output ["5B"]first run]
@quotation
In practice brackets encoding is reasonably useful for normal Put_Line use
-since we won't get confused between left brackets and wide character
+since we won’t get confused between left brackets and wide character
sequences in the output. But for input, or when files are written out
and read back in, it really makes better sense to use one of the standard
encoding methods such as UTF-8.
@@ -21959,7 +22017,7 @@ 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{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2ba}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2ba}
@subsection Stream Pointer Positioning
@@ -21983,7 +22041,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{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bc}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2bc}
@subsection Reading and Writing Non-Regular Files
@@ -22163,7 +22221,7 @@ 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{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2c0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2c0}
@subsection Stream Pointer Positioning
@@ -22390,7 +22448,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{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2ce}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2ce}
@section Open Modes
@@ -22423,11 +22481,11 @@ Append_File
@tab
-"r+"
+“r+”
@tab
-"w+"
+“w+”
@item
@@ -22435,11 +22493,11 @@ In_File
@tab
-"r"
+“r”
@tab
-"w+"
+“w+”
@item
@@ -22447,11 +22505,11 @@ Out_File (Direct_IO)
@tab
-"r+"
+“r+”
@tab
-"w"
+“w”
@item
@@ -22459,11 +22517,11 @@ Out_File (all other cases)
@tab
-"w"
+“w”
@tab
-"w"
+“w”
@item
@@ -22471,11 +22529,11 @@ Inout_File
@tab
-"r+"
+“r+”
@tab
-"w+"
+“w+”
@end multitable
@@ -22493,7 +22551,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{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2d0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2d0}
@section Operations on C Streams
@@ -22653,7 +22711,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{2d1}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d1}@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d2}
@section Interfacing to C Streams
@@ -22746,7 +22804,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{2d3}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d4}
+@anchor{gnat_rm/the_gnat_library doc}@anchor{2d3}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d4}@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}
@chapter The GNAT Library
@@ -22940,7 +22998,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{2d5}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d6}
+@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d5}@anchor{gnat_rm/the_gnat_library id2}@anchor{2d6}
@section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads})
@@ -22974,7 +23032,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{2d9}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2da}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2d9}@anchor{gnat_rm/the_gnat_library id4}@anchor{2da}
@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila1.ads})
@@ -23025,7 +23083,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{2df}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2e0}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2df}@anchor{gnat_rm/the_gnat_library id7}@anchor{2e0}
@section @code{Ada.Containers.Formal_Doubly_Linked_Lists} (@code{a-cfdlli.ads})
@@ -23044,7 +23102,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{2e1}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e2}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e1}@anchor{gnat_rm/the_gnat_library id8}@anchor{2e2}
@section @code{Ada.Containers.Formal_Hashed_Maps} (@code{a-cfhama.ads})
@@ -23063,7 +23121,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{2e3}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e4}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e3}@anchor{gnat_rm/the_gnat_library id9}@anchor{2e4}
@section @code{Ada.Containers.Formal_Hashed_Sets} (@code{a-cfhase.ads})
@@ -23082,7 +23140,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{2e5}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e6}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e5}@anchor{gnat_rm/the_gnat_library id10}@anchor{2e6}
@section @code{Ada.Containers.Formal_Ordered_Maps} (@code{a-cforma.ads})
@@ -23120,7 +23178,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{2e9}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2ea}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2e9}@anchor{gnat_rm/the_gnat_library id12}@anchor{2ea}
@section @code{Ada.Containers.Formal_Vectors} (@code{a-cofove.ads})
@@ -23139,7 +23197,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{2eb}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2ec}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2eb}@anchor{gnat_rm/the_gnat_library id13}@anchor{2ec}
@section @code{Ada.Containers.Formal_Indefinite_Vectors} (@code{a-cfinve.ads})
@@ -23158,7 +23216,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{2ed}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ee}
+@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ed}@anchor{gnat_rm/the_gnat_library id14}@anchor{2ee}
@section @code{Ada.Containers.Functional_Vectors} (@code{a-cofuve.ads})
@@ -23202,7 +23260,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{2f1}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f2}
+@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f1}@anchor{gnat_rm/the_gnat_library id16}@anchor{2f2}
@section @code{Ada.Containers.Functional_Maps} (@code{a-cofuma.ads})
@@ -23249,7 +23307,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{2f7}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f8}
+@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f7}@anchor{gnat_rm/the_gnat_library id19}@anchor{2f8}
@section @code{Ada.Command_Line.Remove} (@code{a-colire.ads})
@@ -23267,7 +23325,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{2f9}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2fa}
+@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2f9}@anchor{gnat_rm/the_gnat_library id20}@anchor{2fa}
@section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads})
@@ -23282,12 +23340,12 @@ see the removed argument.
@geindex handling long command lines
This child of @code{Ada.Command_Line} provides a mechanism facilities for
-getting command line arguments from a text file, called a "response file".
+getting command line arguments from a text file, called a “response file”.
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{2fb}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fc}
+@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fb}@anchor{gnat_rm/the_gnat_library id21}@anchor{2fc}
@section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads})
@@ -23302,7 +23360,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{2fd}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fe}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fd}@anchor{gnat_rm/the_gnat_library id22}@anchor{2fe}
@section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads})
@@ -23316,7 +23374,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{2ff}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{300}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2ff}@anchor{gnat_rm/the_gnat_library id23}@anchor{300}
@section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads})
@@ -23358,7 +23416,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{305}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{306}
+@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{305}@anchor{gnat_rm/the_gnat_library id26}@anchor{306}
@section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads})
@@ -23390,7 +23448,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{309}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{30a}
+@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{309}@anchor{gnat_rm/the_gnat_library id28}@anchor{30a}
@section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads})
@@ -23407,7 +23465,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{30b}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30c}
+@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30b}@anchor{gnat_rm/the_gnat_library id29}@anchor{30c}
@section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads})
@@ -23466,7 +23524,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{313}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{314}
+@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{313}@anchor{gnat_rm/the_gnat_library id33}@anchor{314}
@section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads})
@@ -23479,7 +23537,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{315}@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{316}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{315}@anchor{gnat_rm/the_gnat_library id34}@anchor{316}
@section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads})
@@ -23509,7 +23567,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{319}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{31a}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{319}@anchor{gnat_rm/the_gnat_library id36}@anchor{31a}
@section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads})
@@ -23522,7 +23580,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{31b}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{31c}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{31b}@anchor{gnat_rm/the_gnat_library id37}@anchor{31c}
@section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads})
@@ -23576,7 +23634,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{323}@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{324}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{323}@anchor{gnat_rm/the_gnat_library id41}@anchor{324}
@section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads})
@@ -23610,7 +23668,7 @@ to AltiVec facilities.
@geindex AltiVec
-This package provides public 'View' data types from/to which private
+This package provides public ‘View’ data types from/to which private
vector representations can be converted via
GNAT.Altivec.Conversions. This allows convenient access to individual
vector elements and provides a simple way to initialize vector
@@ -23630,7 +23688,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{32b}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{32c}
+@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{32b}@anchor{gnat_rm/the_gnat_library id45}@anchor{32c}
@section @code{GNAT.AWK} (@code{g-awk.ads})
@@ -23645,7 +23703,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{32d}@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32e}
+@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32d}@anchor{gnat_rm/the_gnat_library id46}@anchor{32e}
@section @code{GNAT.Bind_Environment} (@code{g-binenv.ads})
@@ -23658,7 +23716,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{32f}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{330}
+@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{32f}@anchor{gnat_rm/the_gnat_library id47}@anchor{330}
@section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads})
@@ -23712,7 +23770,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{337}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{338}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{337}@anchor{gnat_rm/the_gnat_library id51}@anchor{338}
@section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads})
@@ -23755,7 +23813,7 @@ multiple instantiations.
@geindex Wide characte representations
Provides a routine which given a string, reads the start of the string to
-see whether it is one of the standard byte order marks (BOM's) which signal
+see whether it is one of the standard byte order marks (BOM’s) which signal
the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.
@@ -23774,7 +23832,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{33f}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{340}
+@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{33f}@anchor{gnat_rm/the_gnat_library id55}@anchor{340}
@section @code{GNAT.Calendar} (@code{g-calend.ads})
@@ -23788,7 +23846,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{341}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{342}
+@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{341}@anchor{gnat_rm/the_gnat_library id56}@anchor{342}
@section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads})
@@ -23799,7 +23857,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{343}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{344}
+@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{343}@anchor{gnat_rm/the_gnat_library id57}@anchor{344}
@section @code{GNAT.CRC32} (@code{g-crc32.ads})
@@ -23816,7 +23874,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{345}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{346}
+@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{345}@anchor{gnat_rm/the_gnat_library id58}@anchor{346}
@section @code{GNAT.Case_Util} (@code{g-casuti.ads})
@@ -23831,7 +23889,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{347}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{348}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{347}@anchor{gnat_rm/the_gnat_library id59}@anchor{348}
@section @code{GNAT.CGI} (@code{g-cgi.ads})
@@ -23873,7 +23931,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{34d}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34e}
+@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34d}@anchor{gnat_rm/the_gnat_library id62}@anchor{34e}
@section @code{GNAT.Command_Line} (@code{g-comlin.ads})
@@ -23904,7 +23962,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{351}@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{352}
+@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{351}@anchor{gnat_rm/the_gnat_library id64}@anchor{352}
@section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads})
@@ -23915,7 +23973,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{353}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{354}
+@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{353}@anchor{gnat_rm/the_gnat_library id65}@anchor{354}
@section @code{GNAT.Current_Exception} (@code{g-curexc.ads})
@@ -23946,7 +24004,7 @@ obtaining information about exceptions provided by Ada 83 compilers.
Provide a debugging storage pools that helps tracking memory corruption
problems.
-See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User's Guide}.
+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{357}@anchor{gnat_rm/the_gnat_library id67}@anchor{358}
@@ -24007,7 +24065,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{35d}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35e}
+@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35d}@anchor{gnat_rm/the_gnat_library id70}@anchor{35e}
@section @code{GNAT.Directory_Operations} (@code{g-dirope.ads})
@@ -24020,7 +24078,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{35f}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{360}
+@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{35f}@anchor{gnat_rm/the_gnat_library id71}@anchor{360}
@section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads})
@@ -24032,7 +24090,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{361}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{362}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{361}@anchor{gnat_rm/the_gnat_library id72}@anchor{362}
@section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads})
@@ -24070,7 +24128,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{365}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{366}
+@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{365}@anchor{gnat_rm/the_gnat_library id74}@anchor{366}
@section @code{GNAT.Encode_String} (@code{g-encstr.ads})
@@ -24140,7 +24198,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{36d}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36e}
+@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36d}@anchor{gnat_rm/the_gnat_library id78}@anchor{36e}
@section @code{GNAT.Exceptions} (@code{g-except.ads})
@@ -24161,7 +24219,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{36f}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{370}
+@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{36f}@anchor{gnat_rm/the_gnat_library id79}@anchor{370}
@section @code{GNAT.Expect} (@code{g-expect.ads})
@@ -24177,7 +24235,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{371}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{372}
+@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{371}@anchor{gnat_rm/the_gnat_library id80}@anchor{372}
@section @code{GNAT.Expect.TTY} (@code{g-exptty.ads})
@@ -24189,7 +24247,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{373}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{374}
+@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{373}@anchor{gnat_rm/the_gnat_library id81}@anchor{374}
@section @code{GNAT.Float_Control} (@code{g-flocon.ads})
@@ -24203,7 +24261,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{375}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{376}
+@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{375}@anchor{gnat_rm/the_gnat_library id82}@anchor{376}
@section @code{GNAT.Formatted_String} (@code{g-forstr.ads})
@@ -24218,7 +24276,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{377}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{378}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{377}@anchor{gnat_rm/the_gnat_library id83}@anchor{378}
@section @code{GNAT.Heap_Sort} (@code{g-heasor.ads})
@@ -24248,7 +24306,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{37b}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{37c}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{37b}@anchor{gnat_rm/the_gnat_library id85}@anchor{37c}
@section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads})
@@ -24262,7 +24320,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{37d}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37e}
+@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37d}@anchor{gnat_rm/the_gnat_library id86}@anchor{37e}
@section @code{GNAT.HTable} (@code{g-htable.ads})
@@ -24275,7 +24333,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{37f}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{380}
+@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{37f}@anchor{gnat_rm/the_gnat_library id87}@anchor{380}
@section @code{GNAT.IO} (@code{g-io.ads})
@@ -24291,7 +24349,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{381}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{382}
+@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{381}@anchor{gnat_rm/the_gnat_library id88}@anchor{382}
@section @code{GNAT.IO_Aux} (@code{g-io_aux.ads})
@@ -24305,7 +24363,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{383}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{384}
+@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{383}@anchor{gnat_rm/the_gnat_library id89}@anchor{384}
@section @code{GNAT.Lock_Files} (@code{g-locfil.ads})
@@ -24319,7 +24377,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{385}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{386}
+@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{385}@anchor{gnat_rm/the_gnat_library id90}@anchor{386}
@section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads})
@@ -24331,7 +24389,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{387}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{388}
+@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{387}@anchor{gnat_rm/the_gnat_library id91}@anchor{388}
@section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads})
@@ -24343,7 +24401,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{389}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{38a}
+@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{389}@anchor{gnat_rm/the_gnat_library id92}@anchor{38a}
@section @code{GNAT.MD5} (@code{g-md5.ads})
@@ -24356,7 +24414,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{38b}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{38c}
+@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{38b}@anchor{gnat_rm/the_gnat_library id93}@anchor{38c}
@section @code{GNAT.Memory_Dump} (@code{g-memdum.ads})
@@ -24429,7 +24487,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{395}@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{25a}
+@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{25a}@anchor{gnat_rm/the_gnat_library id98}@anchor{395}
@section @code{GNAT.Regexp} (@code{g-regexp.ads})
@@ -24442,10 +24500,10 @@ standard Ada library and are more convenient to use.
A simple implementation of regular expressions, using a subset of regular
expression syntax copied from familiar Unix style utilities. This is the
simplest of the three pattern matching packages provided, and is particularly
-suitable for 'file globbing' applications.
+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{396}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{397}
+@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{396}@anchor{gnat_rm/the_gnat_library id99}@anchor{397}
@section @code{GNAT.Registry} (@code{g-regist.ads})
@@ -24459,7 +24517,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{398}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{399}
+@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{398}@anchor{gnat_rm/the_gnat_library id100}@anchor{399}
@section @code{GNAT.Regpat} (@code{g-regpat.ads})
@@ -24474,7 +24532,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{39a}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{39b}
+@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id101}@anchor{39b}
@section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads})
@@ -24496,11 +24554,11 @@ this interface usable for large files or socket streams.
@geindex Secondary Stack Info
-Provide the capability to query the high water mark of the current task's
+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{39e}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39f}
+@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id103}@anchor{39f}
@section @code{GNAT.Semaphores} (@code{g-semaph.ads})
@@ -24562,7 +24620,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{3a8}@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a9}
+@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a8}@anchor{gnat_rm/the_gnat_library id108}@anchor{3a9}
@section @code{GNAT.SHA384} (@code{g-sha384.ads})
@@ -24575,7 +24633,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{3aa}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3ab}
+@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3aa}@anchor{gnat_rm/the_gnat_library id109}@anchor{3ab}
@section @code{GNAT.SHA512} (@code{g-sha512.ads})
@@ -24670,7 +24728,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{3b8}@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b9}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b8}@anchor{gnat_rm/the_gnat_library id116}@anchor{3b9}
@section @code{GNAT.Spitbol} (@code{g-spitbo.ads})
@@ -24717,7 +24775,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{3be}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3bf}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3be}@anchor{gnat_rm/the_gnat_library id119}@anchor{3bf}
@section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads})
@@ -24734,7 +24792,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{3c0}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3c1}
+@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3c0}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c1}
@section @code{GNAT.SSE} (@code{g-sse.ads})
@@ -24767,7 +24825,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{3c6}@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c7}
+@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c6}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c7}
@section @code{GNAT.Strings} (@code{g-string.ads})
@@ -24791,7 +24849,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{3ca}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3cb}
+@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3ca}@anchor{gnat_rm/the_gnat_library id125}@anchor{3cb}
@section @code{GNAT.Table} (@code{g-table.ads})
@@ -24811,7 +24869,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{3cc}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3cd}
+@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3cc}@anchor{gnat_rm/the_gnat_library id126}@anchor{3cd}
@section @code{GNAT.Task_Lock} (@code{g-tasloc.ads})
@@ -24828,7 +24886,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{3ce}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3cf}
+@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3ce}@anchor{gnat_rm/the_gnat_library id127}@anchor{3cf}
@section @code{GNAT.Time_Stamp} (@code{g-timsta.ads})
@@ -24860,7 +24918,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{3d2}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d3}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d2}@anchor{gnat_rm/the_gnat_library id129}@anchor{3d3}
@section @code{GNAT.Traceback} (@code{g-traceb.ads})
@@ -24872,7 +24930,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{3d4}@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d5}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d4}@anchor{gnat_rm/the_gnat_library id130}@anchor{3d5}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -24881,7 +24939,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{3d6}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d7}
+@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d6}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d7}
@section @code{GNAT.UTF_32} (@code{g-table.ads})
@@ -24925,7 +24983,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{3dc}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3dd}
+@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3dc}@anchor{gnat_rm/the_gnat_library id134}@anchor{3dd}
@section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads})
@@ -24965,7 +25023,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{3e2}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e3}
+@anchor{gnat_rm/the_gnat_library id137}@anchor{3e2}@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3e3}
@section @code{Interfaces.C.Extensions} (@code{i-cexten.ads})
@@ -24989,7 +25047,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{3e6}@anchor{gnat_rm/the_gnat_library id139}@anchor{3e7}
+@anchor{gnat_rm/the_gnat_library id139}@anchor{3e6}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e7}
@section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads})
@@ -25004,7 +25062,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{3e8}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e9}
+@anchor{gnat_rm/the_gnat_library id140}@anchor{3e8}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e9}
@section @code{Interfaces.VxWorks} (@code{i-vxwork.ads})
@@ -25020,7 +25078,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{3ea}@anchor{gnat_rm/the_gnat_library id141}@anchor{3eb}
+@anchor{gnat_rm/the_gnat_library id141}@anchor{3ea}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3eb}
@section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads})
@@ -25036,7 +25094,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{3ec}@anchor{gnat_rm/the_gnat_library id142}@anchor{3ed}
+@anchor{gnat_rm/the_gnat_library id142}@anchor{3ec}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3ed}
@section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads})
@@ -25059,7 +25117,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{3ee}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ef}
+@anchor{gnat_rm/the_gnat_library id143}@anchor{3ee}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3ef}
@section @code{System.Address_Image} (@code{s-addima.ads})
@@ -25105,7 +25163,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{3f4}@anchor{gnat_rm/the_gnat_library id146}@anchor{3f5}
+@anchor{gnat_rm/the_gnat_library id146}@anchor{3f4}@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3f5}
@section @code{System.Memory} (@code{s-memory.ads})
@@ -25136,7 +25194,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{3f8}@anchor{gnat_rm/the_gnat_library id148}@anchor{3f9}
+@anchor{gnat_rm/the_gnat_library id148}@anchor{3f8}@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f9}
@section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads})
@@ -25179,7 +25237,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{3fe}@anchor{gnat_rm/the_gnat_library id151}@anchor{3ff}
+@anchor{gnat_rm/the_gnat_library id151}@anchor{3fe}@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3ff}
@section @code{System.Pool_Local} (@code{s-pooloc.ads})
@@ -25212,7 +25270,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{402}@anchor{gnat_rm/the_gnat_library id153}@anchor{403}
+@anchor{gnat_rm/the_gnat_library id153}@anchor{402}@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{403}
@section @code{System.Rident} (@code{s-rident.ads})
@@ -25244,7 +25302,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{406}@anchor{gnat_rm/the_gnat_library id155}@anchor{407}
+@anchor{gnat_rm/the_gnat_library id155}@anchor{406}@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{407}
@section @code{System.Unsigned_Types} (@code{s-unstyp.ads})
@@ -25257,7 +25315,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{408}@anchor{gnat_rm/the_gnat_library id156}@anchor{409}
+@anchor{gnat_rm/the_gnat_library id156}@anchor{408}@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{409}
@section @code{System.Wch_Cnv} (@code{s-wchcnv.ads})
@@ -25290,7 +25348,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{40c}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40d}
+@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{40c}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40d}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}
@chapter Interfacing to Other Languages
@@ -25308,7 +25366,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{40e}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40f}
+@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{40f}
@section Interfacing to C
@@ -25448,7 +25506,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{410}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}
+@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{410}
@section Interfacing to C++
@@ -25523,7 +25581,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{415}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{416}
+@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{415}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{416}
@section Interfacing to non-GNAT Ada code
@@ -25547,7 +25605,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{417}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{418}
+@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{417}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{418}@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}
@chapter Specialized Needs Annexes
@@ -25588,7 +25646,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{419}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{41a}
+@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{41a}@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}
@chapter Implementation of Specific Ada Features
@@ -25601,12 +25659,13 @@ facilities.
* GNAT Implementation of Shared Passive Packages::
* Code Generation for Array Aggregates::
* The Size of Discriminated Records with Default Discriminants::
+* Image Values For Nonscalar Types::
* Strict Conformance to the Ada Reference Manual::
@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{166}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{41b}
+@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{41b}@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{166}
@section Machine Code Insertions
@@ -25671,7 +25730,7 @@ result. The possible values for constraint are the same as those used in
the RTL, and are dependent on the configuration file used to build the
GCC back end. If there are no output operands, then this argument may
either be omitted, or explicitly given as @code{No_Output_Operands}.
-No support is provided for GNU C's symbolic names for output parameters.
+No support is provided for GNU C’s symbolic names for output parameters.
The second argument of @code{my_float'Asm_Output} functions as
though it were an @code{out} parameter, which is a little curious, but
@@ -25690,7 +25749,7 @@ to be a static expression, and is the constraint for the parameter,
value to be used as the input argument. The possible values for the
constraint are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
-No support is provided for GNU C's symbolic names for input parameters.
+No support is provided for GNU C’s symbolic names for input parameters.
If there are no input operands, this argument may either be omitted, or
explicitly given as @code{No_Input_Operands}. The fourth argument, not
@@ -25715,11 +25774,11 @@ Generally it is strongly advisable to use Volatile for any ASM statement
that is missing either input or output operands or to avoid unwanted
optimizations. A warning is generated if this advice is not followed.
-No support is provided for GNU C's @code{asm goto} feature.
+No support is provided for GNU C’s @code{asm goto} feature.
The @code{Asm} subprograms may be used in two ways. First the procedure
forms can be used anywhere a procedure call would be valid, and
-correspond to what the RM calls 'intrinsic' routines. Such calls can
+correspond to what the RM calls ‘intrinsic’ routines. Such calls can
be used to intersperse machine instructions with other Ada statements.
Second, the function forms, which return a dummy value of the limited
private type @code{Asm_Insn}, can be used in code statements, and indeed
@@ -25774,7 +25833,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{41c}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41d}
+@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41c}@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{41d}
@section GNAT Implementation of Tasking
@@ -25790,11 +25849,11 @@ 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{41e}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41f}
+@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41e}@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{41f}
@subsection Mapping Ada Tasks onto the Underlying Kernel Threads
-GNAT's run-time support comprises two layers:
+GNAT’s run-time support comprises two layers:
@itemize *
@@ -25806,12 +25865,12 @@ GNARL (GNAT Run-time Layer)
GNULL (GNAT Low-level Library)
@end itemize
-In GNAT, Ada's tasking services rely on a platform and OS independent
+In GNAT, Ada’s tasking services rely on a platform and OS independent
layer known as GNARL. This code is responsible for implementing the
-correct semantics of Ada's task creation, rendezvous, protected
+correct semantics of Ada’s task creation, rendezvous, protected
operations etc.
-GNARL decomposes Ada's tasking semantics into simpler lower level
+GNARL decomposes Ada’s tasking semantics into simpler lower level
operations such as create a thread, set the priority of a thread,
yield, create a lock, lock/unlock, etc. The spec for these low-level
operations constitutes GNULLI, the GNULL Interface. This interface is
@@ -25859,7 +25918,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{420}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{421}
+@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{421}
@subsection Ensuring Compliance with the Real-Time Annex
@@ -25932,19 +25991,19 @@ and VxWorks.
@code{Concurrent_Readers_Locking} is supported on Linux.
Notes about @code{Ceiling_Locking} on Linux:
-If the process is running as 'root', ceiling locking is used.
+If the process is running as ‘root’, ceiling locking is used.
If the capabilities facility is installed
-("sudo apt-get --assume-yes install libcap-dev" on Ubuntu,
+(“sudo apt-get –assume-yes install libcap-dev” on Ubuntu,
for example),
and the program is linked against that library
-("-largs -lcap"),
+(“-largs -lcap”),
and the executable file has the cap_sys_nice capability
-("sudo /sbin/setcap cap_sys_nice=ep executable_file_name"),
+(“sudo /sbin/setcap cap_sys_nice=ep executable_file_name”),
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{423}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{424}
+@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{423}@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{424}
@section GNAT Implementation of Shared Passive Packages
@@ -26073,7 +26132,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{427}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{428}
+@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{428}
@subsection Static constant aggregates with static bounds
@@ -26135,7 +26194,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{42b}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{42c}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{42b}@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{42c}
@subsection Aggregates with static bounds
@@ -26163,7 +26222,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{42d}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42e}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42d}@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{42e}
@subsection Aggregates with nonstatic bounds
@@ -26174,7 +26233,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{42f}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{430}
+@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{42f}@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{430}
@subsection Aggregates in assignment statements
@@ -26215,7 +26274,7 @@ If any of these conditions are violated, the aggregate will be built in
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
+@node The Size of Discriminated Records with Default Discriminants,Image Values For Nonscalar Types,Code Generation for Array Aggregates,Implementation of Specific Ada Features
@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{431}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{432}
@section The Size of Discriminated Records with Default Discriminants
@@ -26265,8 +26324,8 @@ object, and place it on the stack.
This maximum size approach
has been a source of surprise to some users, who expect the default
values of the discriminants to determine the size reserved for an
-unconstrained object: "If the default is 15, why should the object occupy
-a larger size?"
+unconstrained object: “If the default is 15, why should the object occupy
+a larger size?”
The answer, of course, is that the discriminant may be later modified,
and its full range of values must be taken into account. This is why the
declaration:
@@ -26283,7 +26342,7 @@ is flagged by the compiler with a warning:
an attempt to create @code{Too_Large} will raise @code{Storage_Error},
because the required size includes @code{Positive'Last}
bytes. As the first example indicates, the proper approach is to declare an
-index type of 'reasonable' range so that unconstrained objects are not too
+index type of ‘reasonable’ range so that unconstrained objects are not too
large.
One final wrinkle: if the object is declared to be @code{aliased}, or if it is
@@ -26295,8 +26354,28 @@ aliasing all views of the object (which may be manipulated by different tasks,
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{433}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{434}
+@node Image Values For Nonscalar Types,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 id14}@anchor{433}@anchor{gnat_rm/implementation_of_specific_ada_features image-values-for-nonscalar-types}@anchor{434}
+@section Image Values For Nonscalar Types
+
+
+Ada 2022 defines the Image, Wide_Image, and Wide_Wide image attributes
+for nonscalar types; earlier Ada versions defined these attributes only
+for scalar types. Ada RM 4.10 provides some general guidance regarding
+the default implementation of these attributes and the GNAT compiler
+follows that guidance. However, beyond that the precise details of the
+image text generated in these cases are deliberately not documented and are
+subject to change. In particular, users should not rely on formatting details
+(such as spaces or line breaking), record field order, image values for access
+types, image values for types that have ancestor or subcomponent types
+declared in non-Ada2022 code, image values for predefined types, or the
+compiler’s choices regarding the implementation permissions described in
+Ada RM 4.10. This list is not intended to be exhaustive. If more precise
+control of image text is required for some type T, then T’Put_Image should be
+explicitly specified.
+
+@node Strict Conformance to the Ada Reference Manual,,Image Values For Nonscalar Types,Implementation of Specific Ada Features
+@anchor{gnat_rm/implementation_of_specific_ada_features id15}@anchor{435}@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{436}
@section Strict Conformance to the Ada Reference Manual
@@ -26323,7 +26402,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{435}@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{436}
+@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{437}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{438}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}
@chapter Implementation of Ada 2012 Features
@@ -26357,10 +26436,10 @@ subsequent releases. A date of 0000-00-00 means that GNAT has always
implemented the feature, or implemented it as soon as it appeared as a
binding interpretation.
-Each feature corresponds to an Ada Issue ('AI') approved by the Ada
+Each feature corresponds to an Ada Issue (‘AI’) approved by the Ada
standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2012.
The features are ordered based on the relevant sections of the Ada
-Reference Manual ("RM"). When a given AI relates to multiple points
+Reference Manual (“RM”). When a given AI relates to multiple points
in the RM, the earliest is used.
A complete description of the AIs may be found in
@@ -26446,7 +26525,7 @@ RM References: 2.08 (7) 2.08 (16)
@itemize *
@item
-@emph{AI-0080 'View of' not needed if clear from context (0000-00-00)}
+@emph{AI-0080 ‘View of’ not needed if clear from context (0000-00-00)}
This is an editorial change only, described as non-testable in the AI.
@@ -26462,7 +26541,7 @@ RM References: 3.01 (7)
@emph{AI-0183 Aspect specifications (2010-08-16)}
Aspect specifications have been fully implemented except for pre and post-
-conditions, and type invariants, which have their own separate AI's. All
+conditions, and type invariants, which have their own separate AI’s. All
forms of declarations listed in the AI are supported. The following is a
list of the aspects supported (with GNAT implementation aspects marked)
@end itemize
@@ -26483,7 +26562,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26491,7 +26570,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26535,7 +26614,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26555,7 +26634,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26569,7 +26648,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26577,7 +26656,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26597,7 +26676,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26611,7 +26690,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26643,7 +26722,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26651,7 +26730,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26659,7 +26738,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26697,7 +26776,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26705,7 +26784,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26713,7 +26792,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26733,7 +26812,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26741,7 +26820,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26749,7 +26828,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26757,7 +26836,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26771,7 +26850,7 @@ Source
@tab
--- GNAT
+– GNAT
@item
@@ -26791,7 +26870,7 @@ Source
@tab
--- GNAT
+– GNAT
@end multitable
@@ -26819,8 +26898,8 @@ RM References: 3.02.01 (3) 3.02.02 (2) 3.03.01 (2/2) 3.08 (6)
@item
@emph{AI-0128 Inequality is a primitive operation (0000-00-00)}
-If an equality operator ("=") is declared for a type, then the implicitly
-declared inequality operator ("/=") is a primitive operation of the type.
+If an equality operator (“=”) is declared for a type, then the implicitly
+declared inequality operator (“/=”) is a primitive operation of the type.
This is the only reasonable interpretation, and is the one always implemented
by GNAT, but the RM was not entirely clear in making this point.
@@ -26884,7 +26963,7 @@ RM References: 3.03 (23) 3.10.02 (26/2) 4.01 (9) 6.04.01 (17) 8.05.01 (
@emph{AI-0093 Additional rules use immutably limited (0000-00-00)}
This is an editorial change only, to make more widespread use of the Ada 2012
-'immutably limited'.
+‘immutably limited’.
RM References: 3.03 (23.4/3)
@end itemize
@@ -26952,7 +27031,7 @@ RM References: 3.05 (56/2)
Ada 2012 relaxes the restriction that forbids discriminants of tagged types
to have default expressions by allowing them when the type is limited. It
is often useful to define a default value for a discriminant even though
-it can't be changed by assignment.
+it can’t be changed by assignment.
RM References: 3.07 (9.1/2) 3.07.02 (3)
@end itemize
@@ -27011,7 +27090,7 @@ RM References: 3.09 (7.4/2) 3.09 (12.4/2)
@emph{AI-0076 function with controlling result (0000-00-00)}
This is an editorial change only. The RM defines calls with controlling
-results, but uses the term 'function with controlling result' without an
+results, but uses the term ‘function with controlling result’ without an
explicit definition.
RM References: 3.09.02 (2/2)
@@ -27565,10 +27644,10 @@ RM References: 7.05 (5/2) 12.05.01 (5.1/2)
@item
@emph{AI-0099 Tag determines whether finalization needed (0000-00-00)}
-This AI clarifies that 'needs finalization' is part of dynamic semantics,
+This AI clarifies that ‘needs finalization’ is part of dynamic semantics,
and therefore depends on the run-time characteristics of an object (i.e. its
-tag) and not on its nominal type. As the AI indicates: "we do not expect
-this to affect any implementation'@w{'}.
+tag) and not on its nominal type. As the AI indicates: “we do not expect
+this to affect any implementation’’.
RM References: 7.06.01 (6) 7.06.01 (7) 7.06.01 (8) 7.06.01 (9/2)
@end itemize
@@ -27698,7 +27777,7 @@ C.06 (4) C.06 (6) C.06 (9) C.06 (13) C.06 (14)
@itemize *
@item
-@emph{AI-0072 Task signalling using 'Terminated (0000-00-00)}
+@emph{AI-0072 Task signalling using ‘Terminated (0000-00-00)}
This AI clarifies that task signalling for reading @code{'Terminated} only
occurs if the result is True. GNAT semantics has always been consistent with
@@ -27838,7 +27917,7 @@ RM References: 10.02.01 (15.1/2) 10.02.01 (15.4/2) 10.02.01 (15.5/2) 10.0
@emph{AI-0219 Pure permissions and limited parameters (2010-05-25)}
This AI refines the rules for the cases with limited parameters which do not
-allow the implementations to omit 'redundant'. GNAT now properly conforms
+allow the implementations to omit ‘redundant’. GNAT now properly conforms
to the requirements of this binding interpretation.
RM References: 10.02.01 (18/2)
@@ -28117,7 +28196,7 @@ RM References: 13.13.02 (1.2/2)
@itemize *
@item
-@emph{AI-0109 Redundant check in S'Class'Input (0000-00-00)}
+@emph{AI-0109 Redundant check in S’Class’Input (0000-00-00)}
This AI is an editorial change only. It removes the need for a tag check
that can never fail.
@@ -28179,7 +28258,7 @@ RM References: 13.14 (2) 13.14 (3/1) 13.14 (8.1/1) 13.14 (10) 13.14 (14
@item
@emph{AI-0017 Freezing and incomplete types (0000-00-00)}
-So-called 'Taft-amendment types' (i.e., types that are completed in package
+So-called ‘Taft-amendment types’ (i.e., types that are completed in package
bodies) are not frozen by the occurrence of bodies in the
enclosing declarative part. GNAT always implemented this properly.
@@ -28489,7 +28568,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{437}@anchor{gnat_rm/obsolescent_features doc}@anchor{438}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
+@anchor{gnat_rm/obsolescent_features doc}@anchor{439}@anchor{gnat_rm/obsolescent_features id1}@anchor{43a}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
@chapter Obsolescent Features
@@ -28508,12 +28587,12 @@ compatibility purposes.
@end menu
@node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{439}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{43a}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{43b}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{43c}
@section pragma No_Run_Time
The pragma @code{No_Run_Time} is used to achieve an affect similar
-to the use of the "Zero Foot Print" configurable run time, but without
+to the use of the “Zero Foot Print” configurable run time, but without
requiring a specially configured run time. The result of using this
pragma, which must be used for all units in a partition, is to restrict
the use of any language features requiring run-time support code. The
@@ -28521,7 +28600,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{43b}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{43c}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{43d}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{43e}
@section pragma Ravenscar
@@ -28530,7 +28609,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{43d}@anchor{gnat_rm/obsolescent_features id4}@anchor{43e}
+@anchor{gnat_rm/obsolescent_features id4}@anchor{43f}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{440}
@section pragma Restricted_Run_Time
@@ -28540,7 +28619,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{43f}@anchor{gnat_rm/obsolescent_features id5}@anchor{440}
+@anchor{gnat_rm/obsolescent_features id5}@anchor{441}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{442}
@section pragma Task_Info
@@ -28566,17 +28645,17 @@ 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{441}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{442}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{443}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{444}
@section package System.Task_Info (@code{s-tasinf.ads})
This package provides target dependent functionality that is used
to support the @code{Task_Info} pragma. The predefined Ada package
@code{System.Multiprocessors} and the @code{CPU} aspect now provide a
-standard replacement for GNAT's @code{Task_Info} functionality.
+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{443}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{444}
+@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{445}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{446}
@chapter Compatibility and Porting Guide
@@ -28598,7 +28677,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{445}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{446}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{447}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{448}
@section Writing Portable Fixed-Point Declarations
@@ -28613,7 +28692,7 @@ type F1 is delta 1.0 range -128.0 .. +128.0;
then the implementation is allowed to choose -128.0 .. +127.0 if it
likes, but is not required to do so.
-This leads to possible portability problems, so let's have a closer
+This leads to possible portability problems, so let’s have a closer
look at this, and figure out how to avoid these problems.
First, why does this freedom exist, and why would an implementation
@@ -28623,11 +28702,11 @@ it would need 9 bits to hold the largest positive value (and typically
that means 16 bits on all machines). But if the implementation chooses
the +127.0 bound then it can fit values of the type in 8 bits.
-Why not make the user write +127.0 if that's what is wanted?
+Why not make the user write +127.0 if that’s what is wanted?
The rationale is that if you are thinking of fixed point
-as a kind of 'poor man's floating-point', then you don't want
+as a kind of ‘poor man’s floating-point’, then you don’t want
to be thinking about the scaled integers that are used in its
-representation. Let's take another example:
+representation. Let’s take another example:
@example
type F2 is delta 2.0**(-15) range -1.0 .. +1.0;
@@ -28643,7 +28722,7 @@ type F2 is delta 2.0**(-15) range -1.0 .. +1.0-(2.0**(-15));
@end example
and the Ada language design team felt that this was too annoying
-to require. We don't need to debate this decision at this point,
+to require. We don’t need to debate this decision at this point,
since it is well established (the rule about narrowing the ranges
dates to Ada 83).
@@ -28720,7 +28799,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{447}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{448}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{449}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{44a}
@section Compatibility with Ada 83
@@ -28748,7 +28827,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{449}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{44a}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{44b}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{44c}
@subsection Legal Ada 83 programs that are illegal in Ada 95
@@ -28770,7 +28849,7 @@ For example:
for Char in 'A' .. 'Z' loop ... end loop;
@end example
-The problem is that 'A' and 'Z' could be from either
+The problem is that ‘A’ and ‘Z’ could be from either
@code{Character} or @code{Wide_Character}. The simplest correction
is to make the type explicit; e.g.:
@@ -28833,7 +28912,7 @@ In Ada 83, it was permissible to pass an indefinite type (e.g, @code{String})
as the actual for a generic formal private type, but then the instantiation
would be illegal if there were any instances of declarations of variables
of this type in the generic body. In Ada 95, to avoid this clear violation
-of the methodological principle known as the 'contract model',
+of the methodological principle known as the ‘contract model’,
the generic declaration explicitly indicates whether
or not such instantiations are permitted. If a generic formal parameter
has explicit unknown discriminants, indicated by using @code{(<>)} after the
@@ -28848,7 +28927,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{44b}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{44c}
+@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{44d}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{44e}
@subsection More deterministic semantics
@@ -28876,7 +28955,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{44d}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44e}
+@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44f}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{450}
@subsection Changed semantics
@@ -28918,7 +28997,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{44f}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{450}
+@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{451}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{452}
@subsection Other language compatibility issues
@@ -28936,7 +29015,7 @@ as identifiers as in Ada 83. However,
in practice, it is usually advisable to make the necessary modifications
to the program to remove the need for using this switch.
See the @code{Compiling Different Versions of Ada} section in
-the @cite{GNAT User's Guide}.
+the @cite{GNAT User’s Guide}.
@item
Support for removed Ada 83 pragmas and attributes
@@ -28951,7 +29030,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{451}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{452}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{453}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{454}
@section Compatibility between Ada 95 and Ada 2005
@@ -29008,7 +29087,7 @@ now need to be considered in expression resolution.
@item
@emph{Fixed-point multiplication and division.}
-Certain expressions involving '*' or '/' for a fixed-point type, which
+Certain expressions involving ‘*’ or ‘/’ for a fixed-point type, which
were legal in Ada 95 and invoked the predefined versions of these operations,
are now ambiguous.
The ambiguity may be resolved either by applying a type conversion to the
@@ -29023,7 +29102,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{453}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{454}
+@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{455}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{456}
@section Implementation-dependent characteristics
@@ -29046,7 +29125,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{455}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{456}
+@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{457}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{458}
@subsection Implementation-defined pragmas
@@ -29054,7 +29133,7 @@ Ada compilers are allowed to supplement the language-defined pragmas, and
these are a potential source of non-portability. All GNAT-defined pragmas
are described in @ref{7,,Implementation Defined Pragmas},
and these include several that are specifically
-intended to correspond to other vendors' Ada 83 pragmas.
+intended to correspond to other vendors’ Ada 83 pragmas.
For migrating from VADS, the pragma @code{Use_VADS_Size} may be useful.
For compatibility with HP Ada 83, GNAT supplies the pragmas
@code{Extend_System}, @code{Ident}, @code{Inline_Generic},
@@ -29068,7 +29147,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{457}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{458}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{459}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{45a}
@subsection Implementation-defined attributes
@@ -29076,13 +29155,13 @@ Analogous to pragmas, the set of attributes may be extended by an
implementation. All GNAT-defined attributes are described in
@ref{8,,Implementation Defined Attributes},
and these include several that are specifically intended
-to correspond to other vendors' Ada 83 attributes. For migrating from VADS,
+to correspond to other vendors’ Ada 83 attributes. For migrating from VADS,
the attribute @code{VADS_Size} may be useful. For compatibility with HP
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{459}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{45a}
+@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{45b}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{45c}
@subsection Libraries
@@ -29111,13 +29190,13 @@ 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{45b}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{45c}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{45d}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{45e}
@subsection Elaboration order
The implementation can choose any elaboration order consistent with the unit
dependency relationship. This freedom means that some orders can result in
-Program_Error being raised due to an 'Access Before Elaboration': an attempt
+Program_Error being raised due to an ‘Access Before Elaboration’: an attempt
to invoke a subprogram before its body has been elaborated, or to instantiate
a generic before the generic body has been elaborated. By default GNAT
attempts to choose a safe order (one that will not encounter access before
@@ -29126,7 +29205,7 @@ elaboration problems) by implicitly inserting @code{Elaborate} or
needed. However, this can lead to the creation of elaboration circularities
and a resulting rejection of the program by gnatbind. This issue is
thoroughly described in the @emph{Elaboration Order Handling in GNAT} appendix
-in the @cite{GNAT User's Guide}.
+in the @cite{GNAT User’s Guide}.
In brief, there are several
ways to deal with this situation:
@@ -29147,7 +29226,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{45d}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45e}
+@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45f}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{460}
@subsection Target-specific aspects
@@ -29160,10 +29239,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{45f,,Representation Clauses}.
+GNAT’s approach to these issues is described in @ref{461,,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{460}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{461}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{462}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{463}
@section Compatibility with Other Ada Systems
@@ -29206,7 +29285,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{45f}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{462}
+@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{464}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{461}
@section Representation Clauses
@@ -29236,7 +29315,7 @@ Some Ada 83 compilers allowed a Size specification to cause implicit
packing of an array or record. This could cause expensive implicit
conversions for change of representation in the presence of derived
types, and the Ada design intends to avoid this possibility.
-Subsequent AI's were issued to make it clear that such implicit
+Subsequent AI’s were issued to make it clear that such implicit
change of representation in response to a Size clause is inadvisable,
and this recommendation is represented explicitly in the Ada 95 (and Ada 2005)
Reference Manuals as implementation advice that is followed by GNAT.
@@ -29254,7 +29333,7 @@ on a 32-bit machine, the size of @code{Natural} will typically be 31 and not
32 (since no sign bit is required). Some Ada 83 compilers gave 31, and
some 32 in this situation. This problem will usually show up as a compile
time error, but not always. It is a good idea to check all uses of the
-'Size attribute when porting Ada 83 code. The GNAT specific attribute
+‘Size attribute when porting Ada 83 code. The GNAT specific attribute
Object_Size can provide a useful way of duplicating the behavior of
some Ada 83 compiler systems.
@@ -29265,14 +29344,14 @@ A common assumption in Ada 83 code is that an access type is in fact a pointer,
and that therefore it will be the same size as a System.Address value. This
assumption is true for GNAT in most cases with one exception. For the case of
a pointer to an unconstrained array type (where the bounds may vary from one
-value of the access type to another), the default is to use a 'fat pointer',
+value of the access type to another), the default is to use a ‘fat pointer’,
which is represented as two separate pointers, one to the bounds, and one to
the array. This representation has a number of advantages, including improved
efficiency. However, it may cause some difficulties in porting existing Ada 83
code which makes the assumption that, for example, pointers fit in 32 bits on
a machine with 32-bit addressing.
-To get around this problem, GNAT also permits the use of 'thin pointers' for
+To get around this problem, GNAT also permits the use of ‘thin pointers’ for
access types in this case (where the designated type is an unconstrained array
type). These thin pointers are indeed the same size as a System.Address value.
To specify a thin pointer, use a size clause for the type, for example:
@@ -29299,7 +29378,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{463}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{464}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{465}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{466}
@section Compatibility with HP Ada 83
@@ -29329,7 +29408,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{465}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{466}
+@anchor{share/gnu_free_documentation_license doc}@anchor{467}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{468}
@chapter GNU Free Documentation License
@@ -29344,14 +29423,14 @@ license document, but changing it is not allowed.
@strong{Preamble}
The purpose of this License is to make a manual, textbook, or other
-functional and useful document "free" in the sense of freedom: to
+functional and useful document “free” in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
-This License is a kind of "copyleft", which means that derivative
+This License is a kind of “copyleft”, which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
@@ -29372,17 +29451,17 @@ distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The @strong{Document}, below,
refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "@strong{you}". You accept the license if you
+licensee, and is addressed as “@strong{you}”. You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
-A "@strong{Modified Version}" of the Document means any work containing the
+A “@strong{Modified Version}” of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
-A "@strong{Secondary Section}" is a named appendix or a front-matter section of
+A “@strong{Secondary Section}” is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
+publishers or authors of the Document to the Document’s overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (Thus, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
@@ -29391,7 +29470,7 @@ connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
-The "@strong{Invariant Sections}" are certain Secondary Sections whose titles
+The “@strong{Invariant Sections}” are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
@@ -29399,12 +29478,12 @@ allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
-The "@strong{Cover Texts}" are certain short passages of text that are listed,
+The “@strong{Cover Texts}” are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
-A "@strong{Transparent}" copy of the Document means a machine-readable copy,
+A “@strong{Transparent}” copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
@@ -29415,7 +29494,7 @@ to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
-of text. A copy that is not "Transparent" is called @strong{Opaque}.
+of text. A copy that is not “Transparent” is called @strong{Opaque}.
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
@@ -29428,24 +29507,24 @@ processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
-The "@strong{Title Page}" means, for a printed book, the title page itself,
+The “@strong{Title Page}” means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
+formats which do not have any title page as such, “Title Page” means
+the text near the most prominent appearance of the work’s title,
preceding the beginning of the body of the text.
-The "@strong{publisher}" means any person or entity that distributes
+The “@strong{publisher}” means any person or entity that distributes
copies of the Document to the public.
-A section "@strong{Entitled XYZ}" means a named subunit of the Document whose
+A section “@strong{Entitled XYZ}” means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as "@strong{Acknowledgements}",
-"@strong{Dedications}", "@strong{Endorsements}", or "@strong{History}".)
-To "@strong{Preserve the Title}"
+specific section name mentioned below, such as “@strong{Acknowledgements}”,
+“@strong{Dedications}”, “@strong{Endorsements}”, or “@strong{History}”.)
+To “@strong{Preserve the Title}”
of such a section when you modify the Document means that it remains a
-section "Entitled XYZ" according to this definition.
+section “Entitled XYZ” according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
@@ -29473,7 +29552,7 @@ you may publicly display copies.
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
+Document’s license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
@@ -29550,16 +29629,16 @@ terms of this License, in the form shown in the Addendum below.
@item
Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
+and required Cover Texts given in the Document’s license notice.
@item
Include an unaltered copy of this License.
@item
-Preserve the section Entitled "History", Preserve its Title, and add
+Preserve the section Entitled “History”, Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
-there is no section Entitled "History" in the Document, create one
+there is no section Entitled “History” in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
@@ -29568,13 +29647,13 @@ Version as stated in the previous sentence.
Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
-it was based on. These may be placed in the "History" section.
+it was based on. These may be placed in the “History” section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
@item
-For any section Entitled "Acknowledgements" or "Dedications",
+For any section Entitled “Acknowledgements” or “Dedications”,
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
@@ -29585,11 +29664,11 @@ unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
@item
-Delete any section Entitled "Endorsements". Such a section
+Delete any section Entitled “Endorsements”. Such a section
may not be included in the Modified Version.
@item
-Do not retitle any existing section to be Entitled "Endorsements"
+Do not retitle any existing section to be Entitled “Endorsements”
or to conflict in title with any Invariant Section.
@item
@@ -29600,12 +29679,12 @@ If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
+list of Invariant Sections in the Modified Version’s license notice.
These titles must be distinct from any other section titles.
-You may add a section Entitled "Endorsements", provided it contains
+You may add a section Entitled “Endorsements”, provided it contains
nothing but endorsements of your Modified Version by various
-parties---for example, statements of peer review or that the text has
+parties—for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
@@ -29641,11 +29720,11 @@ author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
-In the combination, you must combine any sections Entitled "History"
+In the combination, you must combine any sections Entitled “History”
in the various original documents, forming one section Entitled
-"History"; likewise combine any sections Entitled "Acknowledgements",
-and any sections Entitled "Dedications". You must delete all sections
-Entitled "Endorsements".
+“History”; likewise combine any sections Entitled “Acknowledgements”,
+and any sections Entitled “Dedications”. You must delete all sections
+Entitled “Endorsements”.
@strong{6. COLLECTIONS OF DOCUMENTS}
@@ -29664,16 +29743,16 @@ other respects regarding verbatim copying of that document.
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an "aggregate" if the copyright
+distribution medium, is called an “aggregate” if the copyright
resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
+of the compilation’s users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
+the entire aggregate, the Document’s Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
@@ -29694,8 +29773,8 @@ of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve
+If a section in the Document is Entitled “Acknowledgements”,
+“Dedications”, or “History”, the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
@@ -29736,37 +29815,37 @@ differ in detail to address new problems or concerns. See
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
+License “or any later version” applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
-License can be used, that proxy's public statement of acceptance of a
+License can be used, that proxy’s public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.
@strong{11. RELICENSING}
-"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
-"Massive Multiauthor Collaboration" (or "MMC") contained in the
+“Massive Multiauthor Collaboration” (or “MMC”) contained in the
site means any set of copyrightable works thus published on the MMC
site.
-"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
-"Incorporate" means to publish or republish a Document, in whole or
+“Incorporate” means to publish or republish a Document, in whole or
in part, as part of another Document.
-An MMC is "eligible for relicensing" if it is licensed under this
+An MMC is “eligible for relicensing” if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole
or in part into the MMC, (1) had no cover texts or invariant sections,
@@ -29789,12 +29868,12 @@ Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-A copy of the license is included in the section entitled "GNU
-Free Documentation License".
+A copy of the license is included in the section entitled “GNU
+Free Documentation License”.
@end quotation
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the "with ... Texts." line with this:
+replace the “with … Texts.” line with this:
@quotation
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index ef68b82..713a662 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -3,7 +3,7 @@
@setfilename gnat_ugn.info
@documentencoding UTF-8
@ifinfo
-@*Generated by Sphinx 1.4.6.@*
+@*Generated by Sphinx 4.0.2.@*
@end ifinfo
@settitle GNAT User's Guide for Native Platforms
@defindex ge
@@ -21,7 +21,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Apr 12, 2021
+GNAT User's Guide for Native Platforms , Jun 23, 2021
AdaCore
@@ -41,7 +41,7 @@ Copyright @copyright{} 2008-2021, Free Software Foundation
@c %** end of user preamble
@ifnottex
-@node Top, About This Guide
+@node Top
@top GNAT User's Guide for Native Platforms
@insertcopying
@end ifnottex
@@ -59,7 +59,7 @@ Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover Texts being
-"GNAT User's Guide for Native Platforms",
+“GNAT User’s Guide for Native Platforms”,
and with no Back-Cover Texts. A copy of the license is
included in the section entitled @ref{1,,GNU Free Documentation License}.
@@ -538,7 +538,7 @@ Other Asm Functionality
@end menu
@node About This Guide,Getting Started with GNAT,Top,Top
-@anchor{gnat_ugn/about_this_guide about-this-guide}@anchor{2}@anchor{gnat_ugn/about_this_guide doc}@anchor{3}@anchor{gnat_ugn/about_this_guide gnat-user-s-guide-for-native-platforms}@anchor{4}@anchor{gnat_ugn/about_this_guide id1}@anchor{5}
+@anchor{gnat_ugn/about_this_guide doc}@anchor{2}@anchor{gnat_ugn/about_this_guide about-this-guide}@anchor{3}@anchor{gnat_ugn/about_this_guide gnat-user-s-guide-for-native-platforms}@anchor{4}@anchor{gnat_ugn/about_this_guide id1}@anchor{5}
@chapter About This Guide
@@ -554,7 +554,7 @@ invoked in Ada 83 compatibility mode.
By default, GNAT assumes Ada 2012, but you can override with a
compiler switch (@ref{6,,Compiling Different Versions of Ada})
to explicitly specify the language version.
-Throughout this manual, references to 'Ada' without a year suffix
+Throughout this manual, references to ‘Ada’ without a year suffix
apply to all Ada versions of the language, starting with Ada 95.
@menu
@@ -721,22 +721,22 @@ Commands that are entered by the user are shown as preceded by a prompt string
comprising the @code{$} character followed by a space.
@item
-Full file names are shown with the '/' character
+Full file names are shown with the ‘/’ character
as the directory separator; e.g., @code{parent-dir/subdir/myfile.adb}.
If you are using GNAT on a Windows platform, please note that
-the '\' character should be used instead.
+the ‘' character should be used instead.
@end itemize
@node Getting Started with GNAT,The GNAT Compilation Model,About This Guide,Top
-@anchor{gnat_ugn/getting_started_with_gnat getting-started-with-gnat}@anchor{8}@anchor{gnat_ugn/getting_started_with_gnat doc}@anchor{14}@anchor{gnat_ugn/getting_started_with_gnat id1}@anchor{15}
+@anchor{gnat_ugn/getting_started_with_gnat doc}@anchor{14}@anchor{gnat_ugn/getting_started_with_gnat getting-started-with-gnat}@anchor{8}@anchor{gnat_ugn/getting_started_with_gnat id1}@anchor{15}
@chapter Getting Started with GNAT
-This chapter describes how to use GNAT's command line interface to build
+This chapter describes how to use GNAT’s command line interface to build
executable Ada programs.
On most platforms a visually oriented Integrated Development Environment
is also available: GNAT Studio.
-GNAT Studio offers a graphical "look and feel", support for development in
+GNAT Studio offers a graphical “look and feel”, support for development in
other programming languages, comprehensive browsing features, and
many other capabilities.
For information on GNAT Studio please refer to the
@@ -780,7 +780,7 @@ machine performing the run. This can be achieved by setting the @code{Object_Dir
project file attribute.
@node Running GNAT,Running a Simple Ada Program,System Requirements,Getting Started with GNAT
-@anchor{gnat_ugn/getting_started_with_gnat running-gnat}@anchor{18}@anchor{gnat_ugn/getting_started_with_gnat id3}@anchor{19}
+@anchor{gnat_ugn/getting_started_with_gnat id3}@anchor{18}@anchor{gnat_ugn/getting_started_with_gnat running-gnat}@anchor{19}
@section Running GNAT
@@ -805,7 +805,7 @@ utility program that, given the name of the main program, automatically
performs the necessary compilation, binding and linking steps.
@node Running a Simple Ada Program,Running a Program with Multiple Units,Running GNAT,Getting Started with GNAT
-@anchor{gnat_ugn/getting_started_with_gnat running-a-simple-ada-program}@anchor{1a}@anchor{gnat_ugn/getting_started_with_gnat id4}@anchor{1b}
+@anchor{gnat_ugn/getting_started_with_gnat id4}@anchor{1a}@anchor{gnat_ugn/getting_started_with_gnat running-a-simple-ada-program}@anchor{1b}
@section Running a Simple Ada Program
@@ -862,7 +862,7 @@ switch must always be present.)
This compile command generates a file
@code{hello.o}, which is the object
file corresponding to your Ada program. It also generates
-an 'Ada Library Information' file @code{hello.ali},
+an ‘Ada Library Information’ file @code{hello.ali},
which contains additional information used to check
that an Ada program is consistent.
@@ -871,7 +871,7 @@ the name of the main file: these tools are builders that will take care of
all the necessary build steps in the correct order.
In particular, these builders automatically recompile any sources that have
been modified since they were last compiled, or sources that depend
-on such modified sources, so that 'version skew' is avoided.
+on such modified sources, so that ‘version skew’ is avoided.
@geindex Version skew (avoided by `@w{`}gnatmake`@w{`})
@@ -972,7 +972,7 @@ $ gnatmake gmain.adb
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node The GNAT Compilation Model,Building Executable Programs with GNAT,Getting Started with GNAT,Top
-@anchor{gnat_ugn/the_gnat_compilation_model doc}@anchor{20}@anchor{gnat_ugn/the_gnat_compilation_model the-gnat-compilation-model}@anchor{9}@anchor{gnat_ugn/the_gnat_compilation_model id1}@anchor{21}
+@anchor{gnat_ugn/the_gnat_compilation_model doc}@anchor{20}@anchor{gnat_ugn/the_gnat_compilation_model id1}@anchor{21}@anchor{gnat_ugn/the_gnat_compilation_model the-gnat-compilation-model}@anchor{9}
@chapter The GNAT Compilation Model
@@ -1054,7 +1054,7 @@ Topics related to source file makeup and naming
@end menu
@node Source Representation,Foreign Language Representation,,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model source-representation}@anchor{22}@anchor{gnat_ugn/the_gnat_compilation_model id2}@anchor{2f}
+@anchor{gnat_ugn/the_gnat_compilation_model id2}@anchor{2f}@anchor{gnat_ugn/the_gnat_compilation_model source-representation}@anchor{22}
@section Source Representation
@@ -1205,7 +1205,7 @@ of the compiler (@ref{31,,Character Set Control}).
The basic character set is Latin-1. This character set is defined by ISO
standard 8859, part 1. The lower half (character codes @code{16#00#}
-... @code{16#7F#)} is identical to standard ASCII coding, but the upper
+… @code{16#7F#)} is identical to standard ASCII coding, but the upper
half is used to represent additional characters. These include extended letters
used by European languages, such as French accents, the vowels with umlauts
used in German, and the extra letter A-ring used in Swedish.
@@ -1220,7 +1220,7 @@ string literals. In addition, the extended characters that represent
letters can be used in identifiers.
@node Other 8-Bit Codes,Wide_Character Encodings,Latin-1,Foreign Language Representation
-@anchor{gnat_ugn/the_gnat_compilation_model other-8-bit-codes}@anchor{34}@anchor{gnat_ugn/the_gnat_compilation_model id5}@anchor{35}
+@anchor{gnat_ugn/the_gnat_compilation_model id5}@anchor{34}@anchor{gnat_ugn/the_gnat_compilation_model other-8-bit-codes}@anchor{35}
@subsection Other 8-Bit Codes
@@ -1368,7 +1368,7 @@ This scheme is compatible with use of the full Wide_Character set.
@geindex Upper-Half Coding
The wide character with encoding @code{16#abcd#} where the upper bit is on
-(in other words, 'a' is in the range 8-F) is represented as two bytes,
+(in other words, ‘a’ is in the range 8-F) is represented as two bytes,
@code{16#ab#} and @code{16#cd#}. The second byte cannot be a format control
character, but is not required to be in the upper half. This method can
be also used for shift-JIS or EUC, where the internal coding matches the
@@ -1429,7 +1429,7 @@ character sequence:
where @code{a}, @code{b}, @code{c}, @code{d} are the four hexadecimal
characters (using uppercase letters) of the wide character code. For
-example, ['A345'] is used to represent the wide character with code
+example, [‘A345’] is used to represent the wide character with code
@code{16#A345#}. It is also possible (though not required) to use the
Brackets coding for upper half characters. For example, the code
@code{16#A3#} can be represented as @code{['A3']}.
@@ -1491,7 +1491,7 @@ twelve byte character sequence:
where @code{a-h} are the six or eight hexadecimal
characters (using uppercase letters) of the wide wide character code. For
-example, ["1F4567"] is used to represent the wide wide character with code
+example, [“1F4567”] is used to represent the wide wide character with code
@code{16#001F_4567#}.
This scheme is compatible with use of the full Wide_Wide_Character set,
@@ -1500,7 +1500,7 @@ ACATS (Ada Conformity Assessment Test Suite) test suite distributions.
@end table
@node File Naming Topics and Utilities,Configuration Pragmas,Foreign Language Representation,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model id8}@anchor{3a}@anchor{gnat_ugn/the_gnat_compilation_model file-naming-topics-and-utilities}@anchor{24}
+@anchor{gnat_ugn/the_gnat_compilation_model file-naming-topics-and-utilities}@anchor{24}@anchor{gnat_ugn/the_gnat_compilation_model id8}@anchor{3a}
@section File Naming Topics and Utilities
@@ -1626,7 +1626,7 @@ Following these rules can result in excessively long
file names if corresponding
unit names are long (for example, if child units or subunits are
heavily nested). An option is available to shorten such long file names
-(called file name 'krunching'). This may be particularly useful when
+(called file name ‘krunching’). This may be particularly useful when
programs being developed with GNAT are to be used on operating systems
with limited file name lengths. @ref{3d,,Using gnatkr}.
@@ -1707,7 +1707,7 @@ then it must be included in the @code{gnatmake} command, it may not
be omitted.
@node Alternative File Naming Schemes,Handling Arbitrary File Naming Conventions with gnatname,Using Other File Names,File Naming Topics and Utilities
-@anchor{gnat_ugn/the_gnat_compilation_model id11}@anchor{40}@anchor{gnat_ugn/the_gnat_compilation_model alternative-file-naming-schemes}@anchor{41}
+@anchor{gnat_ugn/the_gnat_compilation_model alternative-file-naming-schemes}@anchor{40}@anchor{gnat_ugn/the_gnat_compilation_model id11}@anchor{41}
@subsection Alternative File Naming Schemes
@@ -1825,7 +1825,7 @@ pragma Source_File_Name
@end example
Our final example implements a scheme typically used with one of the
-Ada 83 compilers, where the separator character for subunits was '__'
+Ada 83 compilers, where the separator character for subunits was ‘__’
(two underscores), specs were identified by adding @code{_.ADA}, bodies
by adding @code{.ADA}, and subunits by
adding @code{.SEP}. All file names were
@@ -1881,7 +1881,7 @@ a configuration pragmas file (@ref{25,,Configuration Pragmas})
or a project file.
When the non-standard file naming conventions are well-defined,
a small number of pragmas @code{Source_File_Name} specifying a naming pattern
-(@ref{41,,Alternative File Naming Schemes}) may be sufficient. However,
+(@ref{40,,Alternative File Naming Schemes}) may be sufficient. However,
if the file naming conventions are irregular or arbitrary, a number
of pragma @code{Source_File_Name} for individual compilation units
must be defined.
@@ -1891,7 +1891,7 @@ GNAT provides a tool @code{gnatname} to generate the required pragmas for a
set of files.
@node Running gnatname,Switches for gnatname,Arbitrary File Naming Conventions,Handling Arbitrary File Naming Conventions with gnatname
-@anchor{gnat_ugn/the_gnat_compilation_model running-gnatname}@anchor{46}@anchor{gnat_ugn/the_gnat_compilation_model id14}@anchor{47}
+@anchor{gnat_ugn/the_gnat_compilation_model id14}@anchor{46}@anchor{gnat_ugn/the_gnat_compilation_model running-gnatname}@anchor{47}
@subsubsection Running @code{gnatname}
@@ -1934,7 +1934,7 @@ Examples of Naming Patterns are:
For a more complete description of the syntax of Naming Patterns,
see the second kind of regular expressions described in @code{g-regexp.ads}
-(the 'Glob' regular expressions).
+(the ‘Glob’ regular expressions).
When invoked without the switch @code{-P}, @code{gnatname} will create a
configuration pragmas file @code{gnat.adc} in the current working directory,
@@ -2084,7 +2084,7 @@ When a switch @code{-P} is specified,
no switch @code{-c} may be specified.
On all platforms, except on VMS, when @code{gnatname} is invoked for an
existing project file <proj>.gpr, a backup copy of the project file is created
-in the project directory with file name <proj>.gpr.saved_x. 'x' is the first
+in the project directory with file name <proj>.gpr.saved_x. ‘x’ is the first
non negative number that makes this backup copy a new file.
@geindex -v (gnatname)
@@ -2172,7 +2172,7 @@ applying this shortening.
@end menu
@node About gnatkr,Using gnatkr,,File Name Krunching with gnatkr
-@anchor{gnat_ugn/the_gnat_compilation_model id18}@anchor{4e}@anchor{gnat_ugn/the_gnat_compilation_model about-gnatkr}@anchor{4f}
+@anchor{gnat_ugn/the_gnat_compilation_model about-gnatkr}@anchor{4e}@anchor{gnat_ugn/the_gnat_compilation_model id18}@anchor{4f}
@subsubsection About @code{gnatkr}
@@ -2202,7 +2202,7 @@ respectively.
@end itemize
The @code{-gnatk@emph{nn}}
-switch of the compiler activates a 'krunching'
+switch of the compiler activates a ‘krunching’
circuit that limits file names to nn characters (where nn is a decimal
integer).
@@ -2377,7 +2377,7 @@ program @code{gnatkr} is supplied for conveniently determining the
krunched name of a file.
@node Examples of gnatkr Usage,,Krunching Method,File Name Krunching with gnatkr
-@anchor{gnat_ugn/the_gnat_compilation_model id21}@anchor{53}@anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatkr-usage}@anchor{54}
+@anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatkr-usage}@anchor{53}@anchor{gnat_ugn/the_gnat_compilation_model id21}@anchor{54}
@subsubsection Examples of @code{gnatkr} Usage
@@ -2411,7 +2411,7 @@ files to meet the standard GNAT default file naming conventions.
@end menu
@node Handling Files with Multiple Units,Operating gnatchop in Compilation Mode,,Renaming Files with gnatchop
-@anchor{gnat_ugn/the_gnat_compilation_model id23}@anchor{56}@anchor{gnat_ugn/the_gnat_compilation_model handling-files-with-multiple-units}@anchor{57}
+@anchor{gnat_ugn/the_gnat_compilation_model handling-files-with-multiple-units}@anchor{56}@anchor{gnat_ugn/the_gnat_compilation_model id23}@anchor{57}
@subsubsection Handling Files with Multiple Units
@@ -2427,7 +2427,7 @@ Generated or modified project files can be processed by GNAT.
See @ref{42,,Handling Arbitrary File Naming Conventions with gnatname}
for more details on how to use @cite{gnatname}.
-Alternatively, if you want to permanently restructure a set of 'foreign'
+Alternatively, if you want to permanently restructure a set of ‘foreign’
files so that they match the GNAT rules, and do the remaining development
using the GNAT structure, you can simply use @code{gnatchop} once, generate the
new set of files and work with them from that point on.
@@ -2438,7 +2438,7 @@ will each start with a copy of this BOM, meaning that they can be compiled
automatically in UTF-8 mode without needing to specify an explicit encoding.
@node Operating gnatchop in Compilation Mode,Command Line for gnatchop,Handling Files with Multiple Units,Renaming Files with gnatchop
-@anchor{gnat_ugn/the_gnat_compilation_model operating-gnatchop-in-compilation-mode}@anchor{58}@anchor{gnat_ugn/the_gnat_compilation_model id24}@anchor{59}
+@anchor{gnat_ugn/the_gnat_compilation_model id24}@anchor{58}@anchor{gnat_ugn/the_gnat_compilation_model operating-gnatchop-in-compilation-mode}@anchor{59}
@subsubsection Operating gnatchop in Compilation Mode
@@ -2454,7 +2454,7 @@ find this default to be what they want. In this default mode it is incorrect to
submit a file containing only configuration pragmas, or one that ends in
configuration pragmas, to @code{gnatchop}.
-However, using a special option to activate 'compilation mode',
+However, using a special option to activate ‘compilation mode’,
@code{gnatchop}
can perform another function, which is to provide exactly the semantics
required by the RM for handling of configuration pragmas in a compilation.
@@ -2498,7 +2498,7 @@ switch provides the required behavior, and is for example the mode
in which GNAT processes the ACVC tests.
@node Command Line for gnatchop,Switches for gnatchop,Operating gnatchop in Compilation Mode,Renaming Files with gnatchop
-@anchor{gnat_ugn/the_gnat_compilation_model id25}@anchor{5a}@anchor{gnat_ugn/the_gnat_compilation_model command-line-for-gnatchop}@anchor{5b}
+@anchor{gnat_ugn/the_gnat_compilation_model command-line-for-gnatchop}@anchor{5a}@anchor{gnat_ugn/the_gnat_compilation_model id25}@anchor{5b}
@subsubsection Command Line for @code{gnatchop}
@@ -2572,7 +2572,7 @@ no source files written
@end example
@node Switches for gnatchop,Examples of gnatchop Usage,Command Line for gnatchop,Renaming Files with gnatchop
-@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatchop}@anchor{5c}@anchor{gnat_ugn/the_gnat_compilation_model id26}@anchor{5d}
+@anchor{gnat_ugn/the_gnat_compilation_model id26}@anchor{5c}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatchop}@anchor{5d}
@subsubsection Switches for @code{gnatchop}
@@ -2738,7 +2738,7 @@ no attempt is made to add the prefix to the GNAT parser executable.
@end table
@node Examples of gnatchop Usage,,Switches for gnatchop,Renaming Files with gnatchop
-@anchor{gnat_ugn/the_gnat_compilation_model id27}@anchor{5e}@anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatchop-usage}@anchor{5f}
+@anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatchop-usage}@anchor{5e}@anchor{gnat_ugn/the_gnat_compilation_model id27}@anchor{5f}
@subsubsection Examples of @code{gnatchop} Usage
@@ -2779,7 +2779,7 @@ be the one that is output, and earlier duplicate occurrences for a given
unit will be skipped.
@node Configuration Pragmas,Generating Object Files,File Naming Topics and Utilities,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model id28}@anchor{60}@anchor{gnat_ugn/the_gnat_compilation_model configuration-pragmas}@anchor{25}
+@anchor{gnat_ugn/the_gnat_compilation_model configuration-pragmas}@anchor{25}@anchor{gnat_ugn/the_gnat_compilation_model id28}@anchor{60}
@section Configuration Pragmas
@@ -2889,7 +2889,7 @@ Wide_Character_Encoding
@end menu
@node Handling of Configuration Pragmas,The Configuration Pragmas Files,,Configuration Pragmas
-@anchor{gnat_ugn/the_gnat_compilation_model id29}@anchor{61}@anchor{gnat_ugn/the_gnat_compilation_model handling-of-configuration-pragmas}@anchor{3f}
+@anchor{gnat_ugn/the_gnat_compilation_model handling-of-configuration-pragmas}@anchor{3f}@anchor{gnat_ugn/the_gnat_compilation_model id29}@anchor{61}
@subsection Handling of Configuration Pragmas
@@ -2900,7 +2900,7 @@ all compilations performed in a given compilation environment.
GNAT also provides the @code{gnatchop} utility to provide an automatic
way to handle configuration pragmas following the semantics for
compilations (that is, files with multiple units), described in the RM.
-See @ref{58,,Operating gnatchop in Compilation Mode} for details.
+See @ref{59,,Operating gnatchop in Compilation Mode} for details.
However, for most purposes, it will be more convenient to edit the
@code{gnat.adc} file that contains configuration pragmas directly,
as described in the following section.
@@ -2930,7 +2930,7 @@ relevant units). It can appear on a subunit only if it has previously
appeared in the body of spec.
@node The Configuration Pragmas Files,,Handling of Configuration Pragmas,Configuration Pragmas
-@anchor{gnat_ugn/the_gnat_compilation_model the-configuration-pragmas-files}@anchor{62}@anchor{gnat_ugn/the_gnat_compilation_model id30}@anchor{63}
+@anchor{gnat_ugn/the_gnat_compilation_model id30}@anchor{62}@anchor{gnat_ugn/the_gnat_compilation_model the-configuration-pragmas-files}@anchor{63}
@subsection The Configuration Pragmas Files
@@ -2966,7 +2966,7 @@ Files containing configuration pragmas specified with switches
temporary files. A file is considered temporary if its name ends in
@code{.tmp} or @code{.TMP}. Certain tools follow this naming
convention because they pass information to @code{gcc} via
-temporary files that are immediately deleted; it doesn't make sense to
+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}.
@@ -3057,7 +3057,7 @@ checking mode, use the @code{-gnatc} switch.
A given object file clearly depends on the source file which is compiled
-to produce it. Here we are using "depends" in the sense of a typical
+to produce it. Here we are using “depends” in the sense of a typical
@code{make} utility; in other words, an object file depends on a source
file if changes to the source file require the object file to be
recompiled.
@@ -3214,7 +3214,7 @@ see the source of the body of unit @code{Lib.Writ}, contained in file
@code{lib-writ.adb} in the GNAT compiler sources.
@node Binding an Ada Program,GNAT and Libraries,The Ada Library Information Files,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model id34}@anchor{67}@anchor{gnat_ugn/the_gnat_compilation_model binding-an-ada-program}@anchor{29}
+@anchor{gnat_ugn/the_gnat_compilation_model binding-an-ada-program}@anchor{29}@anchor{gnat_ugn/the_gnat_compilation_model id34}@anchor{67}
@section Binding an Ada Program
@@ -3259,7 +3259,7 @@ object files for the Ada units of the program.
This section describes how to build and use libraries with GNAT, and also shows
how to recompile the GNAT run-time library. You should be familiar with the
Project Manager facility (see the @emph{GNAT_Project_Manager} chapter of the
-@emph{GPRbuild User's Guide}) before reading this chapter.
+@emph{GPRbuild User’s Guide}) before reading this chapter.
@menu
* Introduction to Libraries in GNAT::
@@ -3270,7 +3270,7 @@ Project Manager facility (see the @emph{GNAT_Project_Manager} chapter of the
@end menu
@node Introduction to Libraries in GNAT,General Ada Libraries,,GNAT and Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-libraries-in-gnat}@anchor{69}@anchor{gnat_ugn/the_gnat_compilation_model id36}@anchor{6a}
+@anchor{gnat_ugn/the_gnat_compilation_model id36}@anchor{69}@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-libraries-in-gnat}@anchor{6a}
@subsection Introduction to Libraries in GNAT
@@ -3312,7 +3312,7 @@ inlined routine. In the case of @emph{stand-alone libraries} those exposed
units are called @emph{interface units} (@ref{6b,,Stand-alone Ada Libraries}).
All compilation units comprising an application, including those in a library,
-need to be elaborated in an order partially defined by Ada's semantics. GNAT
+need to be elaborated in an order partially defined by Ada’s semantics. GNAT
computes the elaboration order from the @code{ALI} files and this is why they
constitute a mandatory part of GNAT libraries.
@emph{Stand-alone libraries} are the exception to this rule because a specific
@@ -3339,7 +3339,7 @@ using the library.
The easiest way to build a library is to use the Project Manager,
which supports a special type of project called a @emph{Library Project}
(see the @emph{Library Projects} section in the @emph{GNAT Project Manager}
-chapter of the @emph{GPRbuild User's Guide}).
+chapter of the @emph{GPRbuild User’s Guide}).
A project is considered a library project, when two project-level attributes
are defined in it: @code{Library_Name} and @code{Library_Dir}. In order to
@@ -3465,7 +3465,7 @@ or @code{lib@emph{xxx}.so} (or @code{lib@emph{xxx}.dll} on Windows) in order to
be accessed by the directive @code{-l@emph{xxx}} at link time.
@node Installing a library,Using a library,Building a library,General Ada Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model installing-a-library}@anchor{71}@anchor{gnat_ugn/the_gnat_compilation_model id39}@anchor{72}
+@anchor{gnat_ugn/the_gnat_compilation_model id39}@anchor{71}@anchor{gnat_ugn/the_gnat_compilation_model installing-a-library}@anchor{72}
@subsubsection Installing a library
@@ -3475,14 +3475,14 @@ be accessed by the directive @code{-l@emph{xxx}} at link time.
If you use project files, library installation is part of the library build
process (see the @emph{Installing a Library with Project Files} section of the
-@emph{GNAT Project Manager} chapter of the @emph{GPRbuild User's Guide}).
+@emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}).
When project files are not an option, it is also possible, but not recommended,
to install the library so that the sources needed to use the library are on the
Ada source path and the ALI files & libraries be on the Ada Object path (see
@ref{73,,Search Paths and the Run-Time Library (RTL)}. Alternatively, the system
administrator can place general-purpose libraries in the default compiler
-paths, by specifying the libraries' location in the configuration files
+paths, by specifying the libraries’ location in the configuration files
@code{ada_source_path} and @code{ada_object_path}. These configuration files
must be located in the GNAT installation tree at the same place as the gcc spec
file. The location of the gcc spec file can be determined as follows:
@@ -3522,7 +3522,7 @@ library must be installed before the GNAT library if it redefines
any part of it.
@node Using a library,,Installing a library,General Ada Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model using-a-library}@anchor{74}@anchor{gnat_ugn/the_gnat_compilation_model id40}@anchor{75}
+@anchor{gnat_ugn/the_gnat_compilation_model id40}@anchor{74}@anchor{gnat_ugn/the_gnat_compilation_model using-a-library}@anchor{75}
@subsubsection Using a library
@@ -3539,7 +3539,7 @@ project My_Proj is
end My_Proj;
@end example
-Even if you have a third-party, non-Ada library, you can still use GNAT's
+Even if you have a third-party, non-Ada library, you can still use GNAT’s
Project Manager facility to provide a wrapper for it. For example, the
following project, when @emph{with}ed by your main project, will link with the
third-party library @code{liba.a}:
@@ -3616,7 +3616,7 @@ in the directory @code{share/examples/gnat/plugins} within the GNAT
install area.
@node Stand-alone Ada Libraries,Rebuilding the GNAT Run-Time Library,General Ada Libraries,GNAT and Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model stand-alone-ada-libraries}@anchor{6b}@anchor{gnat_ugn/the_gnat_compilation_model id41}@anchor{77}
+@anchor{gnat_ugn/the_gnat_compilation_model id41}@anchor{77}@anchor{gnat_ugn/the_gnat_compilation_model stand-alone-ada-libraries}@anchor{6b}
@subsection Stand-alone Ada Libraries
@@ -3631,11 +3631,11 @@ install area.
@end menu
@node Introduction to Stand-alone Libraries,Building a Stand-alone Library,,Stand-alone Ada Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-stand-alone-libraries}@anchor{78}@anchor{gnat_ugn/the_gnat_compilation_model id42}@anchor{79}
+@anchor{gnat_ugn/the_gnat_compilation_model id42}@anchor{78}@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-stand-alone-libraries}@anchor{79}
@subsubsection Introduction to Stand-alone Libraries
-A Stand-alone Library (abbreviated 'SAL') is a library that contains the
+A Stand-alone Library (abbreviated ‘SAL’) is a library that contains the
necessary code to
elaborate the Ada units that are included in the library. In contrast with
an ordinary library, which consists of all sources, objects and @code{ALI}
@@ -3643,10 +3643,10 @@ files of the
library, a SAL may specify a restricted subset of compilation units
to serve as a library interface. In this case, the fully
self-sufficient set of files will normally consist of an objects
-archive, the sources of interface units' specs, and the @code{ALI}
+archive, the sources of interface units’ specs, and the @code{ALI}
files of interface units.
If an interface spec contains a generic unit or an inlined subprogram,
-the body's
+the body’s
source must also be provided; if the units that must be provided in the source
form depend on other units, the source and @code{ALI} files of those must
also be provided.
@@ -3659,24 +3659,24 @@ version, controlled by @code{Library_Version} attribute, is not changed,
then the clients do not need to be relinked.
SALs also allow the library providers to minimize the amount of library source
-text exposed to the clients. Such 'information hiding' might be useful or
+text exposed to the clients. Such ‘information hiding’ might be useful or
necessary for various reasons.
Stand-alone libraries are also well suited to be used in an executable whose
main routine is not written in Ada.
@node Building a Stand-alone Library,Creating a Stand-alone Library to be used in a non-Ada context,Introduction to Stand-alone Libraries,Stand-alone Ada Libraries
-@anchor{gnat_ugn/the_gnat_compilation_model id43}@anchor{7a}@anchor{gnat_ugn/the_gnat_compilation_model building-a-stand-alone-library}@anchor{7b}
+@anchor{gnat_ugn/the_gnat_compilation_model building-a-stand-alone-library}@anchor{7a}@anchor{gnat_ugn/the_gnat_compilation_model id43}@anchor{7b}
@subsubsection Building a Stand-alone Library
-GNAT's Project facility provides a simple way of building and installing
+GNAT’s Project facility provides a simple way of building and installing
stand-alone libraries; see the @emph{Stand-alone Library Projects} section
-in the @emph{GNAT Project Manager} chapter of the @emph{GPRbuild User's Guide}.
+in the @emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}.
To be a Stand-alone Library Project, in addition to the two attributes
that make a project a Library Project (@code{Library_Name} and
@code{Library_Dir}; see the @emph{Library Projects} section in the
-@emph{GNAT Project Manager} chapter of the @emph{GPRbuild User's Guide}),
+@emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}),
the attribute @code{Library_Interface} must be defined. For example:
@example
@@ -3780,12 +3780,12 @@ the object directory.
Copy the @code{ALI} files of the interface to the library directory,
add in this copy an indication that it is an interface to a SAL
(i.e., add a word @code{SL} on the line in the @code{ALI} file that starts
-with letter 'P') and make the modified copy of the @code{ALI} file
+with letter ‘P’) and make the modified copy of the @code{ALI} file
read-only.
@end itemize
Using SALs is not different from using other libraries
-(see @ref{74,,Using a library}).
+(see @ref{75,,Using a library}).
@node Creating a Stand-alone Library to be used in a non-Ada context,Restrictions in Stand-alone Libraries,Building a Stand-alone Library,Stand-alone Ada Libraries
@anchor{gnat_ugn/the_gnat_compilation_model creating-a-stand-alone-library-to-be-used-in-a-non-ada-context}@anchor{7c}@anchor{gnat_ugn/the_gnat_compilation_model id44}@anchor{7d}
@@ -3813,7 +3813,7 @@ package My_Package is
end My_Package;
@end example
-On the foreign language side, you must provide a 'foreign' view of the
+On the foreign language side, you must provide a ‘foreign’ view of the
library interface; remember that it should contain elaboration routines in
addition to interface subprograms.
@@ -3955,7 +3955,7 @@ experiments or debugging, and is not supported.
@geindex Conditional compilation
@node Conditional Compilation,Mixed Language Programming,GNAT and Libraries,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model id47}@anchor{82}@anchor{gnat_ugn/the_gnat_compilation_model conditional-compilation}@anchor{2b}
+@anchor{gnat_ugn/the_gnat_compilation_model conditional-compilation}@anchor{2b}@anchor{gnat_ugn/the_gnat_compilation_model id47}@anchor{82}
@section Conditional Compilation
@@ -3972,7 +3972,7 @@ gnatprep preprocessor utility.
@end menu
@node Modeling Conditional Compilation in Ada,Preprocessing with gnatprep,,Conditional Compilation
-@anchor{gnat_ugn/the_gnat_compilation_model modeling-conditional-compilation-in-ada}@anchor{83}@anchor{gnat_ugn/the_gnat_compilation_model id48}@anchor{84}
+@anchor{gnat_ugn/the_gnat_compilation_model id48}@anchor{83}@anchor{gnat_ugn/the_gnat_compilation_model modeling-conditional-compilation-in-ada}@anchor{84}
@subsection Modeling Conditional Compilation in Ada
@@ -4167,7 +4167,7 @@ the @code{-gnata} switch is often the most convenient method of controlling
the status of these pragmas.
Note that a pragma is not a statement, so in contexts where a statement
-sequence is required, you can't just write a pragma on its own. You have
+sequence is required, you can’t just write a pragma on its own. You have
to add a @code{null} statement.
@example
@@ -4245,7 +4245,7 @@ constant was introduced as @code{System.Default_Bit_Order}, so you do not
need to define this one yourself).
@node Use of Alternative Implementations,Preprocessing,Conditionalizing Declarations,Modeling Conditional Compilation in Ada
-@anchor{gnat_ugn/the_gnat_compilation_model use-of-alternative-implementations}@anchor{8b}@anchor{gnat_ugn/the_gnat_compilation_model id52}@anchor{8c}
+@anchor{gnat_ugn/the_gnat_compilation_model id52}@anchor{8b}@anchor{gnat_ugn/the_gnat_compilation_model use-of-alternative-implementations}@anchor{8c}
@subsubsection Use of Alternative Implementations
@@ -4279,7 +4279,7 @@ end if;
where @code{Ada_2005} is a Boolean constant.
-But this won't work when @code{Ada_2005} is set to @code{False},
+But this won’t work when @code{Ada_2005} is set to @code{False},
since the @code{then} clause will be illegal for an Ada 95 compiler.
(Recall that although such unreachable code would eventually be deleted
by the compiler, it still needs to be legal. If it uses features
@@ -4308,7 +4308,7 @@ have two files
and the build script renames the appropriate file to @code{file_queries-insert.adb} and then carries out the compilation.
-This can also be done with project files' naming schemes. For example:
+This can also be done with project files’ naming schemes. For example:
@example
for body ("File_Queries.Insert") use "file_queries-insert-2005.ada";
@@ -4365,11 +4365,11 @@ VMS-compatible AST handling. The GNAT build script knows the architecture
and operating system, and automatically selects the right version,
renaming it if necessary to @code{s-asthan.adb} before the run-time build.
-Another style for arranging alternative implementations is through Ada's
+Another style for arranging alternative implementations is through Ada’s
access-to-subprogram facility.
In case some functionality is to be conditionally included,
you can declare an access-to-procedure variable @code{Ref} that is initialized
-to designate a 'do nothing' procedure, and then invoke @code{Ref.all}
+to designate a ‘do nothing’ procedure, and then invoke @code{Ref.all}
when appropriate.
In some library package, set @code{Ref} to @code{Proc'Access} for some
procedure @code{Proc} that performs the relevant processing.
@@ -4379,7 +4379,7 @@ The same idea can also be implemented using tagged types and dispatching
calls.
@node Preprocessing,,Use of Alternative Implementations,Modeling Conditional Compilation in Ada
-@anchor{gnat_ugn/the_gnat_compilation_model preprocessing}@anchor{8d}@anchor{gnat_ugn/the_gnat_compilation_model id53}@anchor{8e}
+@anchor{gnat_ugn/the_gnat_compilation_model id53}@anchor{8d}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing}@anchor{8e}
@subsubsection Preprocessing
@@ -4433,7 +4433,7 @@ For more details on this approach, see @ref{90,,Integrated Preprocessing}.
@geindex Preprocessing (gnatprep)
-This section discusses how to use GNAT's @code{gnatprep} utility for simple
+This section discusses how to use GNAT’s @code{gnatprep} utility for simple
preprocessing.
Although designed for use with GNAT, @code{gnatprep} does not depend on any
special GNAT features.
@@ -4460,7 +4460,7 @@ normal Ada (case-insensitive) rules for its syntax, with the restriction that
all characters need to be in the ASCII set (no accented letters).
@node Using gnatprep,Switches for gnatprep,Preprocessing Symbols,Preprocessing with gnatprep
-@anchor{gnat_ugn/the_gnat_compilation_model using-gnatprep}@anchor{94}@anchor{gnat_ugn/the_gnat_compilation_model id56}@anchor{95}
+@anchor{gnat_ugn/the_gnat_compilation_model id56}@anchor{94}@anchor{gnat_ugn/the_gnat_compilation_model using-gnatprep}@anchor{95}
@subsubsection Using @code{gnatprep}
@@ -4518,7 +4518,7 @@ optional, and can be replaced by the use of the @code{-D} switch.
@end itemize
@node Switches for gnatprep,Form of Definitions File,Using gnatprep,Preprocessing with gnatprep
-@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatprep}@anchor{96}@anchor{gnat_ugn/the_gnat_compilation_model id57}@anchor{97}
+@anchor{gnat_ugn/the_gnat_compilation_model id57}@anchor{96}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatprep}@anchor{97}
@subsubsection Switches for @code{gnatprep}
@@ -4699,7 +4699,7 @@ the usual @code{--},
and comments may be added to the definitions lines.
@node Form of Input Text for gnatprep,,Form of Definitions File,Preprocessing with gnatprep
-@anchor{gnat_ugn/the_gnat_compilation_model id59}@anchor{9a}@anchor{gnat_ugn/the_gnat_compilation_model form-of-input-text-for-gnatprep}@anchor{9b}
+@anchor{gnat_ugn/the_gnat_compilation_model form-of-input-text-for-gnatprep}@anchor{9a}@anchor{gnat_ugn/the_gnat_compilation_model id59}@anchor{9b}
@subsubsection Form of Input Text for @code{gnatprep}
@@ -4741,8 +4741,8 @@ In this example, <expression> is defined by the following grammar:
<expression> ::= ( <expression> )
@end example
-Note the following restriction: it is not allowed to have "and" or "or"
-following "not" in the same expression without parentheses. For example, this
+Note the following restriction: it is not allowed to have “and” or “or”
+following “not” in the same expression without parentheses. For example, this
is not allowed:
@example
@@ -4768,7 +4768,7 @@ literal integer as defined in the Ada Reference Manual, such as 3, 16#FF# or
2#11#. The symbol value must also be a non negative integer. Integer values
in the range 0 .. 2**31-1 are supported.
-The test (<expression> ::= <symbol>'Defined) is true only if
+The test (<expression> ::= <symbol>’Defined) is true only if
the symbol has been defined in the definition file or by a @code{-D}
switch on the command line. Otherwise, the test is false.
@@ -4784,8 +4784,8 @@ or @code{False}.
The use of the @code{not} operator inverts the sense of this logical test.
The @code{not} operator cannot be combined with the @code{or} or @code{and}
-operators, without parentheses. For example, "if not X or Y then" is not
-allowed, but "if (not X) or Y then" and "if not (X or Y) then" are.
+operators, without parentheses. For example, “if not X or Y then” is not
+allowed, but “if (not X) or Y then” and “if not (X or Y) then” are.
The @code{then} keyword is optional as shown
@@ -4905,7 +4905,7 @@ that relate to integrated preprocessing.
This switch specifies the file name (without directory
information) of the preprocessor data file. Either place this file
in one of the source directories, or, when using project
-files, reference the project file's directory via the
+files, reference the project file’s directory via the
@code{project_name'Project_Dir} project attribute; e.g:
@quotation
@@ -4931,7 +4931,7 @@ preprocessing.
Empty lines and comments (using Ada syntax) are also permitted, with no
semantic effect.
-Here's an example of a preprocessor data file:
+Here’s an example of a preprocessor data file:
@quotation
@@ -4970,7 +4970,7 @@ A preprocessor control line has the following syntax:
@end quotation
Thus each preprocessor control line starts with either a literal string or
-the character '*':
+the character ‘*’:
@itemize *
@@ -4980,16 +4980,16 @@ A literal string is the file name (without directory information) of the source
file that will be input to the preprocessor.
@item
-The character '*' is a wild-card indicator; the additional parameters on the line
+The character ‘*’ is a wild-card indicator; the additional parameters on the line
indicate the preprocessing for all the sources
that are not specified explicitly on other lines (the order of the lines is not
significant).
@end itemize
It is an error to have two lines with the same file name or two
-lines starting with the character '*'.
+lines starting with the character ‘*’.
-After the file name or '*', an optional literal string specifies the name of
+After the file name or ‘*’, an optional literal string specifies the name of
the definition file to be used for preprocessing
(@ref{98,,Form of Definitions File}). The definition files are found by the
compiler in one of the source directories. In some cases, when compiling
@@ -5014,7 +5014,7 @@ it cancels the effect of @code{-c}.
Causes both preprocessor lines and the lines deleted
by preprocessing to be retained as comments marked
-with the special string '@cite{--!}'.
+with the special string ‘@cite{–!}’.
@item @code{-D@emph{symbol}=@emph{new_value}}
@@ -5083,7 +5083,7 @@ the output file will be @code{foo.adb.prep}.
@end table
@node Mixed Language Programming,GNAT and Other Compilation Models,Conditional Compilation,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model mixed-language-programming}@anchor{2c}@anchor{gnat_ugn/the_gnat_compilation_model id61}@anchor{9d}
+@anchor{gnat_ugn/the_gnat_compilation_model id61}@anchor{9d}@anchor{gnat_ugn/the_gnat_compilation_model mixed-language-programming}@anchor{2c}
@section Mixed Language Programming
@@ -5102,13 +5102,13 @@ with a focus on combining Ada with C or C++.
@end menu
@node Interfacing to C,Calling Conventions,,Mixed Language Programming
-@anchor{gnat_ugn/the_gnat_compilation_model interfacing-to-c}@anchor{9e}@anchor{gnat_ugn/the_gnat_compilation_model id62}@anchor{9f}
+@anchor{gnat_ugn/the_gnat_compilation_model id62}@anchor{9e}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-to-c}@anchor{9f}
@subsection Interfacing to C
Interfacing Ada with a foreign language such as C involves using
compiler directives to import and/or export entity definitions in each
-language -- using @code{extern} statements in C, for instance, and the
+language – using @code{extern} statements in C, for instance, and the
@code{Import}, @code{Export}, and @code{Convention} pragmas in Ada.
A full treatment of these topics is provided in Appendix B, section 1
of the Ada Reference Manual.
@@ -5283,7 +5283,7 @@ end Unit2;
@end example
The build procedure for this application is similar to the last
-example's:
+example’s:
@itemize *
@@ -5436,7 +5436,7 @@ in section B.4 of the Ada Reference Manual.
Data will be passed according to the conventions described
in section B.3 of the Ada Reference Manual.
-A note on interfacing to a C 'varargs' function:
+A note on interfacing to a C ‘varargs’ function:
@quotation
@@ -5542,7 +5542,7 @@ The return type must be the same as the type of the first argument. The size
of this type can only be 8, 16, 32, or 64.
@item
-Binary arithmetic operators: '+', '-', '*', '/'.
+Binary arithmetic operators: ‘+’, ‘-‘, ‘*’, ‘/’.
The corresponding operator declaration must have parameters and result type
that have the same root numeric type (for example, all three are long_float
types). This simplifies the definition of operations that use type checking
@@ -5579,7 +5579,7 @@ pragma Import (Intrinsic, builtin_sqrt, "__builtin_sqrtf");
@end example
Most of the GCC builtins are accessible this way, and as for other
-import conventions (e.g. C), it is the user's responsibility to ensure
+import conventions (e.g. C), it is the user’s responsibility to ensure
that the Ada subprogram profile matches the underlying builtin
expectations.
@end itemize
@@ -5653,7 +5653,7 @@ identifier (for example in an @code{Import} pragma) with the same
meaning as Fortran.
@node Building Mixed Ada and C++ Programs,Generating Ada Bindings for C and C++ headers,Calling Conventions,Mixed Language Programming
-@anchor{gnat_ugn/the_gnat_compilation_model id64}@anchor{a3}@anchor{gnat_ugn/the_gnat_compilation_model building-mixed-ada-and-c-programs}@anchor{a4}
+@anchor{gnat_ugn/the_gnat_compilation_model building-mixed-ada-and-c-programs}@anchor{a3}@anchor{gnat_ugn/the_gnat_compilation_model id64}@anchor{a4}
@subsection Building Mixed Ada and C++ Programs
@@ -5677,7 +5677,7 @@ challenge. This section gives a few hints that should make this task easier.
GNAT supports interfacing with the G++ compiler (or any C++ compiler
generating code that is compatible with the G++ Application Binary
-Interface ---see @indicateurl{http://www.codesourcery.com/archives/cxx-abi}).
+Interface —see @indicateurl{http://www.codesourcery.com/archives/cxx-abi}).
Interfacing can be done at 3 levels: simple data, subprograms, and
classes. In the first two cases, GNAT offers a specific @code{Convention C_Plus_Plus}
@@ -5751,7 +5751,7 @@ important to note that environment variables such as
at the same time and may make one of the two compilers operate
improperly if set during invocation of the wrong compiler. It is also
very important that the linker uses the proper @code{libgcc.a} GCC
-library -- that is, the one from the C++ compiler installation. The
+library – that is, the one from the C++ compiler installation. The
implicit link command as suggested in the @code{gnatmake} command
from the former example can be replaced by an explicit link command with
the full-verbosity option in order to verify which library is used:
@@ -5793,7 +5793,7 @@ $ gnatlink ada_unit file1.o file2.o --LINK=./my_script
where CC is the name of the non-GNU C++ compiler.
-If the "zero cost" exception mechanism is used, and the platform
+If the “zero cost” exception mechanism is used, and the platform
supports automatic registration of exception tables (e.g., Solaris),
paths to more objects are required:
@@ -5806,8 +5806,8 @@ gcc -print-file-name=crtend.o
$ gnatlink ada_unit file1.o file2.o --LINK=./my_script
@end example
-If the "zero cost exception" mechanism is used, and the platform
-doesn't support automatic registration of exception tables (e.g., HP-UX
+If the “zero cost exception” mechanism is used, and the platform
+doesn’t support automatic registration of exception tables (e.g., HP-UX
or AIX), the simple approach described above will not work and
a pre-linking phase using GNAT will be necessary.
@end itemize
@@ -5817,7 +5817,7 @@ which has a large knowledge base and knows how to link Ada and C++ code
together automatically in most cases.
@node A Simple Example,Interfacing with C++ constructors,Linking a Mixed C++ & Ada Program,Building Mixed Ada and C++ Programs
-@anchor{gnat_ugn/the_gnat_compilation_model id67}@anchor{aa}@anchor{gnat_ugn/the_gnat_compilation_model a-simple-example}@anchor{ab}
+@anchor{gnat_ugn/the_gnat_compilation_model a-simple-example}@anchor{aa}@anchor{gnat_ugn/the_gnat_compilation_model id67}@anchor{ab}
@subsubsection A Simple Example
@@ -6143,7 +6143,7 @@ by means of a limited aggregate. Any further action associated with
the constructor can be placed inside the construct.
@node Interfacing with C++ at the Class Level,,Interfacing with C++ constructors,Building Mixed Ada and C++ Programs
-@anchor{gnat_ugn/the_gnat_compilation_model interfacing-with-c-at-the-class-level}@anchor{ae}@anchor{gnat_ugn/the_gnat_compilation_model id69}@anchor{af}
+@anchor{gnat_ugn/the_gnat_compilation_model id69}@anchor{af}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-with-c-at-the-class-level}@anchor{ae}
@subsubsection Interfacing with C++ at the Class Level
@@ -6389,7 +6389,7 @@ int main ()
@end example
@node Generating Ada Bindings for C and C++ headers,Generating C Headers for Ada Specifications,Building Mixed Ada and C++ Programs,Mixed Language Programming
-@anchor{gnat_ugn/the_gnat_compilation_model id70}@anchor{b0}@anchor{gnat_ugn/the_gnat_compilation_model generating-ada-bindings-for-c-and-c-headers}@anchor{a7}
+@anchor{gnat_ugn/the_gnat_compilation_model generating-ada-bindings-for-c-and-c-headers}@anchor{a7}@anchor{gnat_ugn/the_gnat_compilation_model id70}@anchor{b0}
@subsection Generating Ada Bindings for C and C++ headers
@@ -6457,7 +6457,7 @@ $ gcc -c *.ads
will generate, under GNU/Linux, the following files: @code{time_h.ads},
@code{bits_time_h.ads}, @code{stddef_h.ads}, @code{bits_types_h.ads} which
correspond to the files @code{/usr/include/time.h},
-@code{/usr/include/bits/time.h}, etc..., and will then compile these Ada specs
+@code{/usr/include/bits/time.h}, etc…, and will then compile these Ada specs
in Ada 2005 mode.
The @code{-C} switch tells @code{gcc} to extract comments from headers,
@@ -6534,7 +6534,7 @@ $ g++ -c -fdump-ada-spec readline1.h
@end example
@node Generating Bindings for C++ Headers,Switches,Running the Binding Generator,Generating Ada Bindings for C and C++ headers
-@anchor{gnat_ugn/the_gnat_compilation_model id72}@anchor{b3}@anchor{gnat_ugn/the_gnat_compilation_model generating-bindings-for-c-headers}@anchor{b4}
+@anchor{gnat_ugn/the_gnat_compilation_model generating-bindings-for-c-headers}@anchor{b3}@anchor{gnat_ugn/the_gnat_compilation_model id72}@anchor{b4}
@subsubsection Generating Bindings for C++ Headers
@@ -6794,7 +6794,7 @@ You can then @code{include} @code{pack1.h} from a C source file and use the type
call subprograms, reference objects, and constants.
@node GNAT and Other Compilation Models,Using GNAT Files with External Tools,Mixed Language Programming,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model id74}@anchor{ba}@anchor{gnat_ugn/the_gnat_compilation_model gnat-and-other-compilation-models}@anchor{2d}
+@anchor{gnat_ugn/the_gnat_compilation_model gnat-and-other-compilation-models}@anchor{2d}@anchor{gnat_ugn/the_gnat_compilation_model id74}@anchor{ba}
@section GNAT and Other Compilation Models
@@ -6816,7 +6816,7 @@ used for Ada 83.
The GNAT model of compilation is close to the C and C++ models. You can
think of Ada specs as corresponding to header files in C. As in C, you
-don't need to compile specs; they are compiled when they are used. The
+don’t need to compile specs; they are compiled when they are used. The
Ada @emph{with} is similar in effect to the @code{#include} of a C
header.
@@ -6854,7 +6854,7 @@ model, as described in the Ada Reference Manual.
@geindex GNAT library
-In GNAT, there is no 'library' in the normal sense. Instead, the set of
+In GNAT, there is no ‘library’ in the normal sense. Instead, the set of
source files themselves acts as the library. Compiling Ada programs does
not generate any centralized information, but rather an object file and
a ALI file, which are of interest only to the binder and linker.
@@ -6912,7 +6912,7 @@ of rules saying what source files must be present when a file is
compiled.
@node Using GNAT Files with External Tools,,GNAT and Other Compilation Models,The GNAT Compilation Model
-@anchor{gnat_ugn/the_gnat_compilation_model using-gnat-files-with-external-tools}@anchor{2e}@anchor{gnat_ugn/the_gnat_compilation_model id77}@anchor{bf}
+@anchor{gnat_ugn/the_gnat_compilation_model id77}@anchor{bf}@anchor{gnat_ugn/the_gnat_compilation_model using-gnat-files-with-external-tools}@anchor{2e}
@section Using GNAT Files with External Tools
@@ -6926,7 +6926,7 @@ used with tools designed for other languages.
@end menu
@node Using Other Utility Programs with GNAT,The External Symbol Naming Scheme of GNAT,,Using GNAT Files with External Tools
-@anchor{gnat_ugn/the_gnat_compilation_model using-other-utility-programs-with-gnat}@anchor{c0}@anchor{gnat_ugn/the_gnat_compilation_model id78}@anchor{c1}
+@anchor{gnat_ugn/the_gnat_compilation_model id78}@anchor{c0}@anchor{gnat_ugn/the_gnat_compilation_model using-other-utility-programs-with-gnat}@anchor{c1}
@subsection Using Other Utility Programs with GNAT
@@ -6941,7 +6941,7 @@ gprof (a profiling program), gdb (the FSF debugger), and utilities such
as Purify.
@node The External Symbol Naming Scheme of GNAT,,Using Other Utility Programs with GNAT,Using GNAT Files with External Tools
-@anchor{gnat_ugn/the_gnat_compilation_model the-external-symbol-naming-scheme-of-gnat}@anchor{c2}@anchor{gnat_ugn/the_gnat_compilation_model id79}@anchor{c3}
+@anchor{gnat_ugn/the_gnat_compilation_model id79}@anchor{c2}@anchor{gnat_ugn/the_gnat_compilation_model the-external-symbol-naming-scheme-of-gnat}@anchor{c3}
@subsection The External Symbol Naming Scheme of GNAT
@@ -7000,7 +7000,7 @@ the external name of this procedure will be @code{_ada_hello}.
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node Building Executable Programs with GNAT,GNAT Utility Programs,The GNAT Compilation Model,Top
-@anchor{gnat_ugn/building_executable_programs_with_gnat building-executable-programs-with-gnat}@anchor{a}@anchor{gnat_ugn/building_executable_programs_with_gnat doc}@anchor{c4}@anchor{gnat_ugn/building_executable_programs_with_gnat id1}@anchor{c5}
+@anchor{gnat_ugn/building_executable_programs_with_gnat doc}@anchor{c4}@anchor{gnat_ugn/building_executable_programs_with_gnat building-executable-programs-with-gnat}@anchor{a}@anchor{gnat_ugn/building_executable_programs_with_gnat id1}@anchor{c5}
@chapter Building Executable Programs with GNAT
@@ -7031,7 +7031,7 @@ in a GNAT context (see @ref{70,,Using the GNU make Utility}).
@end menu
@node Building with gnatmake,Compiling with gcc,,Building Executable Programs with GNAT
-@anchor{gnat_ugn/building_executable_programs_with_gnat the-gnat-make-program-gnatmake}@anchor{c6}@anchor{gnat_ugn/building_executable_programs_with_gnat building-with-gnatmake}@anchor{ca}
+@anchor{gnat_ugn/building_executable_programs_with_gnat building-with-gnatmake}@anchor{ca}@anchor{gnat_ugn/building_executable_programs_with_gnat the-gnat-make-program-gnatmake}@anchor{c6}
@section Building with @code{gnatmake}
@@ -7080,7 +7080,7 @@ dependencies, they will always be tracked exactly correctly by
Note that for advanced forms of project structure, we recommend creating
a project file as explained in the @emph{GNAT_Project_Manager} chapter in the
-@emph{GPRbuild User's Guide}, and using the
+@emph{GPRbuild User’s Guide}, and using the
@code{gprbuild} tool which supports building with project files and works similarly
to @code{gnatmake}.
@@ -7095,7 +7095,7 @@ to @code{gnatmake}.
@end menu
@node Running gnatmake,Switches for gnatmake,,Building with gnatmake
-@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatmake}@anchor{cb}@anchor{gnat_ugn/building_executable_programs_with_gnat id2}@anchor{cc}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id2}@anchor{cb}@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatmake}@anchor{cc}
@subsection Running @code{gnatmake}
@@ -7130,7 +7130,7 @@ All @code{gnatmake} output (except when you specify @code{-M}) is sent to
@code{-M} switch is sent to @code{stdout}.
@node Switches for gnatmake,Mode Switches for gnatmake,Running gnatmake,Building with gnatmake
-@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gnatmake}@anchor{cd}@anchor{gnat_ugn/building_executable_programs_with_gnat id3}@anchor{ce}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id3}@anchor{cd}@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gnatmake}@anchor{ce}
@subsection Switches for @code{gnatmake}
@@ -7218,7 +7218,7 @@ itself must not include any embedded spaces.
@item @code{--create-map-file}
When linking an executable, create a map file. The name of the map file
-has the same name as the executable with extension ".map".
+has the same name as the executable with extension “.map”.
@item @code{--create-map-file=@emph{mapfile}}
@@ -7266,7 +7266,7 @@ to process the project files, especially when looking for sources that take a
long time. If the source info file exists but cannot be parsed successfully,
the Project Manager will attempt to recreate it. If the Project Manager fails
to create the source info file, a message is issued, but gnatmake does not
-fail. @code{gnatmake} "trusts" the source info file. This means that
+fail. @code{gnatmake} “trusts” the source info file. This means that
if the source files have changed (addition, deletion, moving to a different
source directory), then the source info file need to be deleted and recreated.
@end table
@@ -7346,7 +7346,7 @@ the objects.
Use a temporary mapping file. A mapping file is a way to communicate
to the compiler two mappings: from unit names to file names (without
any directory information) and from file names to path names (with
-full directory information). A mapping file can make the compiler's
+full directory information). A mapping file can make the compiler’s
file searches faster, especially if there are many source directories,
or the sources are read over a slow network connection. If
@code{-P} is used, a mapping file is always used, so
@@ -7433,7 +7433,7 @@ directories, but is not needed in other cases.
@geindex naming scheme
This also assumes that no directory matches the naming scheme for files (for
-instance that you do not have a directory called "sources.ads" when using the
+instance that you do not have a directory called “sources.ads” when using the
default GNAT naming scheme).
When you do not have to use this switch (i.e., by default), gnatmake is able to
@@ -7462,7 +7462,7 @@ instead of standard error.
@item @code{-f}
Force recompilations. Recompile all sources, even though some object
-files may be up to date, but don't recompile predefined or GNAT internal
+files may be up to date, but don’t recompile predefined or GNAT internal
files or locked files (files with a write-protected ALI file),
unless the @code{-a} switch is also specified.
@end table
@@ -7540,7 +7540,7 @@ rerun the make process with n set to 1 to get a clean list of messages.
@item @code{-k}
Keep going. Continue as much as possible after a compilation error. To
-ease the programmer's task in case of compilation errors, the list of
+ease the programmer’s task in case of compilation errors, the list of
sources for which the compile fails is given when @code{gnatmake}
terminates.
@@ -7624,7 +7624,7 @@ are never reported.
@item @code{-n}
-Don't compile, bind, or link. Checks if all objects are up to date.
+Don’t compile, bind, or link. Checks if all objects are up to date.
If they are not, the full name of the first file that needs to be
recompiled is printed.
Repeated use of this option, followed by compiling the indicated source
@@ -7691,7 +7691,7 @@ Quiet. When this flag is not set, the commands carried out by
Recompile if compiler switches have changed since last compilation.
All compiler switches but -I and -o are taken into account in the
following way:
-orders between different 'first letter' switches are ignored, but
+orders between different ‘first letter’ switches are ignored, but
orders between same switches are taken into account. For example,
@code{-O -O2} is different than @code{-O2 -O}, but @code{-g -O}
is equivalent to @code{-O -g}.
@@ -8095,12 +8095,12 @@ that the debugging information may be out of date.
@end itemize
@node How gnatmake Works,Examples of gnatmake Usage,Notes on the Command Line,Building with gnatmake
-@anchor{gnat_ugn/building_executable_programs_with_gnat id6}@anchor{d4}@anchor{gnat_ugn/building_executable_programs_with_gnat how-gnatmake-works}@anchor{d5}
+@anchor{gnat_ugn/building_executable_programs_with_gnat how-gnatmake-works}@anchor{d4}@anchor{gnat_ugn/building_executable_programs_with_gnat id6}@anchor{d5}
@subsection How @code{gnatmake} Works
Generally @code{gnatmake} automatically performs all necessary
-recompilations and you don't need to worry about how it works. However,
+recompilations and you don’t need to worry about how it works. However,
it may be useful to have some basic understanding of the @code{gnatmake}
approach and in particular to understand how it uses the results of
previous compilations without incorrectly depending on them.
@@ -8123,7 +8123,7 @@ files.
This process ensures that @code{gnatmake} only trusts the dependencies
in an existing ALI file if they are known to be correct. Otherwise it
always recompiles to determine a new, guaranteed accurate set of
-dependencies. As a result the program is compiled 'upside down' from what may
+dependencies. As a result the program is compiled ‘upside down’ from what may
be more familiar as the required order of compilation in some other Ada
systems. In particular, clients are compiled before the units on which
they depend. The ability of GNAT to compile in any order is critical in
@@ -8365,7 +8365,7 @@ names separated by colons (semicolons when working with the NT version).
The content of the @code{ada_source_path} file which is part of the GNAT
installation tree and is used to store standard libraries such as the
GNAT Run Time Library (RTL) source files.
-@ref{71,,Installing a library}
+@ref{72,,Installing a library}
@end itemize
Specifying the switch @code{-I-}
@@ -8448,7 +8448,7 @@ described above), or you will receive a fatal error message.
@end itemize
@node Examples,,Order of Compilation Issues,Compiling with gcc
-@anchor{gnat_ugn/building_executable_programs_with_gnat id12}@anchor{df}@anchor{gnat_ugn/building_executable_programs_with_gnat examples}@anchor{e0}
+@anchor{gnat_ugn/building_executable_programs_with_gnat examples}@anchor{df}@anchor{gnat_ugn/building_executable_programs_with_gnat id12}@anchor{e0}
@subsection Examples
@@ -8515,7 +8515,7 @@ compilation units.
@end menu
@node Alphabetical List of All Switches,Output and Error Message Control,,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat id13}@anchor{e2}@anchor{gnat_ugn/building_executable_programs_with_gnat alphabetical-list-of-all-switches}@anchor{e3}
+@anchor{gnat_ugn/building_executable_programs_with_gnat alphabetical-list-of-all-switches}@anchor{e2}@anchor{gnat_ugn/building_executable_programs_with_gnat id13}@anchor{e3}
@subsection Alphabetical List of All Switches
@@ -8541,7 +8541,7 @@ system configuration. You must have a GNAT cross-compiler built if
Load compiler executables (for example, @code{gnat1}, the Ada compiler)
from @code{dir} instead of the default location. Only use this switch
when multiple versions of the GNAT compiler are available.
-See the "Options for Directory Search" section in the
+See the “Options for Directory Search” section in the
@cite{Using the GNU Compiler Collection (GCC)} manual for further details.
You would normally use the @code{-b} or @code{-V} switch instead.
@end table
@@ -8888,7 +8888,7 @@ Generate brief messages to @code{stderr} even if verbose mode set.
@item @code{-gnatB}
-Assume no invalid (bad) values except for 'Valid attribute use
+Assume no invalid (bad) values except for ‘Valid attribute use
(@ref{e7,,Validity Checking}).
@end table
@@ -9015,7 +9015,7 @@ ALI files.
Specify a configuration pragma file
(the equal sign is optional)
-(@ref{62,,The Configuration Pragmas Files}).
+(@ref{63,,The Configuration Pragmas Files}).
@end table
@geindex -gnateC (gcc)
@@ -9505,7 +9505,7 @@ and attribute_definition_clause for the following attributes:
Address, Alignment, Bit_Order, Component_Size, Machine_Radix,
Object_Size, Scalar_Storage_Order, Size, Small, Stream_Size,
and Value_Size. Pragma Default_Scalar_Storage_Order is also ignored.
-Note that this option should be used only for compiling -- the
+Note that this option should be used only for compiling – the
code is likely to malfunction at run time.
@end table
@@ -9554,7 +9554,7 @@ Calls to subprograms defined in instances
Entry calls
@item
-Indirect calls using 'Access
+Indirect calls using ‘Access
@item
Requeue statements
@@ -9764,7 +9764,7 @@ Cancel effect of previous @code{-gnatp} switch.
@item @code{-gnatq}
-Don't quit. Try semantics, even if parse errors.
+Don’t quit. Try semantics, even if parse errors.
@end table
@geindex -gnatQ (gcc)
@@ -9774,7 +9774,7 @@ Don't quit. Try semantics, even if parse errors.
@item @code{-gnatQ}
-Don't quit. Generate @code{ALI} and tree files even if illegalities.
+Don’t quit. Generate @code{ALI} and tree files even if illegalities.
Note that code generation is still suppressed in the presence of any
errors, so even with @code{-gnatQ} no object file is generated.
@end table
@@ -9849,7 +9849,7 @@ List units for this compilation.
@item @code{-gnatU}
-Tag all error messages with the unique string 'error:'
+Tag all error messages with the unique string ‘error:’
@end table
@geindex -gnatv (gcc)
@@ -10088,7 +10088,7 @@ exit status.
@item @code{--RTS=@emph{rts-path}}
Specifies the default location of the run-time library. Same meaning as the
-equivalent @code{gnatmake} flag (@ref{cd,,Switches for gnatmake}).
+equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}).
@end table
@geindex -S (gcc)
@@ -10197,27 +10197,27 @@ switches, and only one of them may appear in the command line.
The switch @code{-gnat-p} may not be combined with any other switch.
@item
-Once a 'y' appears in the string (that is a use of the @code{-gnaty}
+Once a ‘y’ appears in the string (that is a use of the @code{-gnaty}
switch), then all further characters in the switch are interpreted
as style modifiers (see description of @code{-gnaty}).
@item
-Once a 'd' appears in the string (that is a use of the @code{-gnatd}
+Once a ‘d’ appears in the string (that is a use of the @code{-gnatd}
switch), then all further characters in the switch are interpreted
as debug flags (see description of @code{-gnatd}).
@item
-Once a 'w' appears in the string (that is a use of the @code{-gnatw}
+Once a ‘w’ appears in the string (that is a use of the @code{-gnatw}
switch), then all further characters in the switch are interpreted
as warning mode modifiers (see description of @code{-gnatw}).
@item
-Once a 'V' appears in the string (that is a use of the @code{-gnatV}
+Once a ‘V’ appears in the string (that is a use of the @code{-gnatV}
switch), then all further characters in the switch are interpreted
as validity checking options (@ref{e7,,Validity Checking}).
@item
-Option 'em', 'ec', 'ep', 'l=' and 'R' must be the last options in
+Option ‘em’, ‘ec’, ‘ep’, ‘l=’ and ‘R’ must be the last options in
a combined list of options.
@end itemize
@@ -10228,7 +10228,7 @@ a combined list of options.
@geindex stderr
-The standard default format for error messages is called 'brief format'.
+The standard default format for error messages is called ‘brief format’.
Brief format messages are written to @code{stderr} (the standard error
file) and have the following form:
@@ -10352,7 +10352,7 @@ then the output is written to file xyz.adb.lst.
@item @code{-gnatU}
This switch forces all error messages to be preceded by the unique
-string 'error:'. This means that error messages take a few more
+string ‘error:’. This means that error messages take a few more
characters in space, but allows easy searching for and identification
of error messages.
@end table
@@ -10480,7 +10480,7 @@ is longer than nn characters.
@item @code{-gnatq}
-The @code{q} stands for quit (really 'don't quit').
+The @code{q} stands for quit (really ‘don’t quit’).
In normal operation mode, the compiler first parses the program and
determines if there are any syntax errors. If there are, appropriate
error messages are generated and compilation is immediately terminated.
@@ -10517,7 +10517,7 @@ since ALI files are never generated if @code{-gnats} is set.
@end table
@node Warning Message Control,Debugging and Assertion Control,Output and Error Message Control,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat warning-message-control}@anchor{eb}@anchor{gnat_ugn/building_executable_programs_with_gnat id15}@anchor{f0}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id15}@anchor{f0}@anchor{gnat_ugn/building_executable_programs_with_gnat warning-message-control}@anchor{eb}
@subsection Warning Message Control
@@ -10950,10 +10950,10 @@ for conditional compilation in Ada, and this would generate too many
false positive warnings.
This warning option also activates a special test for comparisons using
-the operators '>=' and' <='.
+the operators ‘>=’ and’ <=’.
If the compiler can tell that only the equality condition is possible,
-then it will warn that the '>' or '<' part of the test
-is useless and that the operator could be replaced by '='.
+then it will warn that the ‘>’ or ‘<’ part of the test
+is useless and that the operator could be replaced by ‘=’.
An example would be comparing a @code{Natural} variable <= 0.
This warning option also generates warnings if
@@ -11119,7 +11119,7 @@ of the pragma @code{Restriction_Warnings}.
@emph{[warning-as-error]}
Used to tag warning messages that have been converted to error messages by
use of the pragma Warning_As_Error. Note that such warnings are prefixed by
-the string "error: " rather than "warning: ".
+the string “error: ” rather than “warning: “.
@item
@emph{[enabled by default]}
@@ -11356,7 +11356,7 @@ implementation unit, defined as any unit from the @code{Ada},
or @code{System}
hierarchies that is not
documented in either the Ada Reference Manual or the GNAT
-Programmer's Reference Manual. Such units are intended only
+Programmer’s Reference Manual. Such units are intended only
for internal implementation purposes and should not be @emph{with}ed
by user programs. The default is that such warnings are generated
@end table
@@ -11575,8 +11575,8 @@ This switch suppresses warnings for possible elaboration problems.
@emph{List inherited aspects.}
This switch causes the compiler to list inherited invariants,
-preconditions, and postconditions from Type_Invariant'Class, Invariant'Class,
-Pre'Class, and Post'Class aspects. Also list inherited subtype predicates.
+preconditions, and postconditions from Type_Invariant’Class, Invariant’Class,
+Pre’Class, and Post’Class aspects. Also list inherited subtype predicates.
@end table
@geindex -gnatw.L (gcc)
@@ -11821,7 +11821,7 @@ ordering when the list of arguments are all simple identifiers that
match the names of the formals, but are in a different order. The
warning is suppressed if any use of named parameter notation is used,
so this is the appropriate way to suppress a false positive (and
-serves to emphasize that the "misordering" is deliberate). The
+serves to emphasize that the “misordering” is deliberate). The
default is that such warnings are not given.
@end table
@@ -11911,7 +11911,7 @@ then the remaining components whose length is fixed and not a multiple
of the storage unit,
@item
-then the remaining components whose length doesn't depend on discriminants
+then the remaining components whose length doesn’t depend on discriminants
(that is to say, with variable but uniform length for all objects),
@item
@@ -12188,7 +12188,7 @@ This switch activates warnings to be generated for entities that
are declared but not referenced, and for units that are @emph{with}ed
and not
referenced. In the case of packages, a warning is also generated if
-no entities in the package are referenced. This means that if a with'ed
+no entities in the package are referenced. This means that if a with’ed
package is referenced but the only references are in @code{use}
clauses or @code{renames}
declarations, a warning is still generated. A warning is also generated
@@ -12297,7 +12297,7 @@ may not be properly initialized.
@emph{Activate info messages for non-default bit order.}
-This switch activates messages (labeled "info", they are not warnings,
+This switch activates messages (labeled “info”, they are not warnings,
just informational messages) about the effects of non-default bit-order
on records to which a component clause is applied. The effect of specifying
non-default bit ordering is a bit subtle (and changed with Ada 2005), so
@@ -12330,7 +12330,7 @@ non-default bit order on record components with component clauses.
@emph{Activate warnings on wrong low bound assumption.}
This switch activates warnings for indexing an unconstrained string parameter
-with a literal or S'Length. This is a case where the code is assuming that the
+with a literal or S’Length. This is a case where the code is assuming that the
low bound is one, which is in general not true (for example when a slice is
passed). The default is that such warnings are generated.
@end table
@@ -12345,7 +12345,7 @@ passed). The default is that such warnings are generated.
@emph{Suppress warnings on wrong low bound assumption.}
This switch suppresses warnings for indexing an unconstrained string parameter
-with a literal or S'Length. Note that this warning can also be suppressed
+with a literal or S’Length. Note that this warning can also be suppressed
in a particular case by adding an assertion that the lower bound is 1,
as shown in the following example:
@@ -12865,7 +12865,7 @@ pragma Assertion_Policy
@end example
The pragmas @code{Assert} and @code{Debug} normally have no effect and
-are ignored. This switch, where @code{a} stands for 'assert', causes
+are ignored. This switch, where @code{a} stands for ‘assert’, causes
pragmas @code{Assert} and @code{Debug} to be activated. This switch also
causes preconditions, postconditions, subtype predicates, and
type invariants to be activated.
@@ -12907,7 +12907,7 @@ is @code{False}, the exception @code{Assert_Failure} is raised.
@end table
@node Validity Checking,Style Checking,Debugging and Assertion Control,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat validity-checking}@anchor{e7}@anchor{gnat_ugn/building_executable_programs_with_gnat id17}@anchor{f3}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id17}@anchor{f3}@anchor{gnat_ugn/building_executable_programs_with_gnat validity-checking}@anchor{e7}
@subsection Validity Checking
@@ -13209,7 +13209,7 @@ enforce specified style rules. A limited set of style rules has been used
in writing the GNAT sources themselves. This switch allows user programs
to activate all or some of these checks. If the source program fails a
specified style check, an appropriate message is given, preceded by
-the character sequence '(style)'. This message does not prevent
+the character sequence ‘(style)’. This message does not prevent
successful compilation (unless the @code{-gnatwe} switch is used).
Note that this is by no means intended to be a general facility for
@@ -13747,7 +13747,7 @@ with declarations.
@emph{Check separate specs.}
-Separate declarations ('specs') are required for subprograms (a
+Separate declarations (‘specs’) are required for subprograms (a
body is not allowed to serve as its own declaration). The only
exception is that parameterless library level procedures are
not required to have a separate declaration. This exception covers
@@ -13923,7 +13923,7 @@ a requirement for no following space.
If any of these style rules is violated, a message is generated giving
details on the violation. The initial characters of such messages are
-always '@cite{(style)}'. Note that these messages are treated as warning
+always ‘@cite{(style)}’. Note that these messages are treated as warning
messages, so they normally do not prevent the generation of an object
file. The @code{-gnatwe} switch can be used to treat warning messages,
including style messages, as fatal errors.
@@ -13936,7 +13936,7 @@ built-in standard style check options are enabled.
The switch @code{-gnatyN} clears any previously set style checks.
@node Run-Time Checks,Using gcc for Syntax Checking,Style Checking,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat run-time-checks}@anchor{ea}@anchor{gnat_ugn/building_executable_programs_with_gnat id19}@anchor{f5}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id19}@anchor{f5}@anchor{gnat_ugn/building_executable_programs_with_gnat run-time-checks}@anchor{ea}
@subsection Run-Time Checks
@@ -13984,7 +13984,7 @@ required, to omit the checking code. If the run-time cost of the
checking code is zero or near-zero, the compiler will generate it even
if checks are suppressed. In particular, if the compiler can prove
that a certain check will necessarily fail, it will generate code to
-do an unconditional 'raise', even if checks are suppressed. The
+do an unconditional ‘raise’, even if checks are suppressed. The
compiler warns in this case. Another case in which checks may not be
eliminated is when they are embedded in certain run-time routines such
as math library routines.
@@ -14050,8 +14050,8 @@ This switch cancels the effect of a previous @code{gnatp} switch.
This switch controls the mode used for computing intermediate
arithmetic integer operations, and also enables overflow checking.
For a full description of overflow mode and checking control, see
-the 'Overflow Check Handling in GNAT' appendix in this
-User's Guide.
+the ‘Overflow Check Handling in GNAT’ appendix in this
+User’s Guide.
Overflow checks are always enabled by this switch. The argument
controls the mode, using the codes
@@ -14168,7 +14168,7 @@ the program source.
@item @code{-gnats}
-The @code{s} stands for 'syntax'.
+The @code{s} stands for ‘syntax’.
Run GNAT in syntax checking only mode. For
example, the command
@@ -14225,7 +14225,7 @@ together. This is primarily used by the @code{gnatchop} utility
@item @code{-gnatc}
-The @code{c} stands for 'check'.
+The @code{c} stands for ‘check’.
Causes the compiler to operate in semantic check mode,
with full checking for all illegalities specified in the
Ada Reference Manual, but without generation of any object code
@@ -14408,7 +14408,7 @@ extensions, see the GNAT reference manual, @code{Pragma Extensions_Allowed}.
@end table
@node Character Set Control,File Naming Control,Compiling Different Versions of Ada,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat id23}@anchor{fb}@anchor{gnat_ugn/building_executable_programs_with_gnat character-set-control}@anchor{31}
+@anchor{gnat_ugn/building_executable_programs_with_gnat character-set-control}@anchor{31}@anchor{gnat_ugn/building_executable_programs_with_gnat id23}@anchor{fb}
@subsection Character Set Control
@@ -14591,7 +14591,7 @@ methods see @ref{37,,Wide_Character Encodings}.
Note that brackets coding is always accepted, even if one of the other
options is specified, so for example @code{-gnatW8} specifies that both
brackets and UTF-8 encodings will be recognized. The units that are
-with'ed directly or indirectly will be scanned using the specified
+with’ed directly or indirectly will be scanned using the specified
representation scheme, and so if one of the non-brackets scheme is
used, it must be used consistently throughout the program. However,
since brackets encoding is always recognized, it may be conveniently
@@ -14646,7 +14646,7 @@ This is a common mode for many programs with foreign language comments.
@item @code{-gnatk@emph{n}}
-Activates file name 'krunching'. @code{n}, a decimal integer in the range
+Activates file name ‘krunching’. @code{n}, a decimal integer in the range
1-999, indicates the maximum allowable length of a file name (not
including the @code{.ads} or @code{.adb} extension). The default is not
to enable file name krunching.
@@ -14655,7 +14655,7 @@ For the source file naming rules, @ref{3b,,File Naming Rules}.
@end table
@node Subprogram Inlining Control,Auxiliary Output Control,File Naming Control,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat subprogram-inlining-control}@anchor{fe}@anchor{gnat_ugn/building_executable_programs_with_gnat id25}@anchor{ff}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id25}@anchor{fe}@anchor{gnat_ugn/building_executable_programs_with_gnat subprogram-inlining-control}@anchor{ff}
@subsection Subprogram Inlining Control
@@ -14666,7 +14666,7 @@ For the source file naming rules, @ref{3b,,File Naming Rules}.
@item @code{-gnatn[12]}
-The @code{n} here is intended to suggest the first syllable of the word 'inline'.
+The @code{n} here is intended to suggest the first syllable of the word ‘inline’.
GNAT recognizes and processes @code{Inline} pragmas. However, for inlining to
actually occur, optimization must be enabled and, by default, inlining of
subprograms across units is not performed. If you want to additionally
@@ -15020,7 +15020,7 @@ is set).
For @code{-gnatR3}, symbolic expressions for values that are computed
at run time for records are included. These symbolic expressions have
a mostly obvious format with #n being used to represent the value of the
-n'th discriminant. See source files @code{repinfo.ads/adb} in the
+n’th discriminant. See source files @code{repinfo.ads/adb} in the
GNAT sources for full details on the format of @code{-gnatR3} output.
For @code{-gnatR4}, information for relevant compiler-generated types
@@ -15097,10 +15097,10 @@ emitted in the debug information.
Historically, old debug formats like stabs were not powerful enough to
express some Ada types (for instance, variant records or fixed-point types).
To work around this, GNAT introduced proprietary encodings that embed the
-missing information ("GNAT encodings").
+missing information (“GNAT encodings”).
Recent versions of the DWARF debug information format are now able to
-correctly describe most of these Ada constructs ("standard DWARF"). As
+correctly describe most of these Ada constructs (“standard DWARF”). As
third-party tools started to use this format, GNAT has been enhanced to
generate it. However, most tools (including GDB) are still relying on GNAT
encodings.
@@ -15127,7 +15127,7 @@ encodings for the rest.
@end table
@node Exception Handling Control,Units to Sources Mapping Files,Debugging Control,Compiler Switches
-@anchor{gnat_ugn/building_executable_programs_with_gnat id28}@anchor{105}@anchor{gnat_ugn/building_executable_programs_with_gnat exception-handling-control}@anchor{106}
+@anchor{gnat_ugn/building_executable_programs_with_gnat exception-handling-control}@anchor{105}@anchor{gnat_ugn/building_executable_programs_with_gnat id28}@anchor{106}
@subsection Exception Handling Control
@@ -15139,7 +15139,7 @@ need for tracing stack frames. This method provides very fast
exception propagation, but introduces significant overhead for
the use of exception handlers, even if no exception is raised.
-The other approach is called 'zero cost' exception handling.
+The other approach is called ‘zero cost’ exception handling.
With this method, the compiler builds static tables to describe
the exception ranges. No dynamic code is required when entering
a frame containing an exception handler. When an exception is
@@ -15150,7 +15150,7 @@ the propagation of exceptions, but there is no overhead for
exception handlers if no exception is raised. Note that in this
mode and in the context of mixed Ada and C/C++ programming,
to propagate an exception through a C/C++ code, the C/C++ code
-must be compiled with the @code{-funwind-tables} GCC's
+must be compiled with the @code{-funwind-tables} GCC’s
option.
The following switches may be used to control which of the
@@ -15195,7 +15195,7 @@ is available for the target in use, otherwise it will generate an error.
The same option @code{--RTS} must be used both for @code{gcc}
and @code{gnatbind}. Passing this option to @code{gnatmake}
-(@ref{cd,,Switches for gnatmake}) will ensure the required consistency
+(@ref{ce,,Switches for gnatmake}) will ensure the required consistency
through the compilation and binding steps.
@node Units to Sources Mapping Files,Code Generation Control,Exception Handling Control,Compiler Switches
@@ -15280,7 +15280,7 @@ there is no point in using @code{-m} switches to improve performance
unless you actually see a performance improvement.
@node Linker Switches,Binding with gnatbind,Compiler Switches,Building Executable Programs with GNAT
-@anchor{gnat_ugn/building_executable_programs_with_gnat linker-switches}@anchor{10a}@anchor{gnat_ugn/building_executable_programs_with_gnat id31}@anchor{10b}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id31}@anchor{10a}@anchor{gnat_ugn/building_executable_programs_with_gnat linker-switches}@anchor{10b}
@section Linker Switches
@@ -15351,7 +15351,7 @@ to be read by the @code{gnatlink} utility used to link the Ada application.
@end menu
@node Running gnatbind,Switches for gnatbind,,Binding with gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatbind}@anchor{10d}@anchor{gnat_ugn/building_executable_programs_with_gnat id33}@anchor{10e}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id33}@anchor{10d}@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatbind}@anchor{10e}
@subsection Running @code{gnatbind}
@@ -15594,7 +15594,7 @@ Output complete list of elaboration-order dependencies.
@item @code{-Ea}
Store tracebacks in exception occurrences when the target supports it.
-The "a" is for "address"; tracebacks will contain hexadecimal addresses,
+The “a” is for “address”; tracebacks will contain hexadecimal addresses,
unless symbolic tracebacks are enabled.
See also the packages @code{GNAT.Traceback} and
@@ -15611,7 +15611,7 @@ Note that on x86 ports, you must not use @code{-fomit-frame-pointer}
@item @code{-Es}
Store tracebacks in exception occurrences when the target supports it.
-The "s" is for "symbolic"; symbolic tracebacks are enabled.
+The “s” is for “symbolic”; symbolic tracebacks are enabled.
@end table
@geindex -E (gnatbind)
@@ -15759,10 +15759,10 @@ limitations:
@itemize *
@item
-Starting the program's execution in the debugger will cause it to
+Starting the program’s execution in the debugger will cause it to
stop at the start of the @code{main} function instead of the main subprogram.
This can be worked around by manually inserting a breakpoint on that
-subprogram and resuming the program's execution until reaching that breakpoint.
+subprogram and resuming the program’s execution until reaching that breakpoint.
@item
Programs using GNAT.Compiler_Version will not link.
@@ -15791,7 +15791,7 @@ Do not look for library files in the system default directory.
@item @code{--RTS=@emph{rts-path}}
Specifies the default location of the run-time library. Same meaning as the
-equivalent @code{gnatmake} flag (@ref{cd,,Switches for gnatmake}).
+equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}).
@geindex -o (gnatbind)
@@ -15943,7 +15943,7 @@ scheduling policy to @code{FIFO_Within_Priorities}.
Enable dynamic stack usage, with @code{n} results stored and displayed
at program termination. A result is generated when a task
-terminates. Results that can't be stored are displayed on the fly, at
+terminates. Results that can’t be stored are displayed on the fly, at
task termination. This option is currently not supported on Itanium
platforms. (See @ref{113,,Dynamic Stack Usage Analysis} for details.)
@@ -16079,7 +16079,7 @@ case the checking against sources has already been performed by
@end table
@node Binder Error Message Control,Elaboration Control,Consistency-Checking Modes,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id36}@anchor{116}@anchor{gnat_ugn/building_executable_programs_with_gnat binder-error-message-control}@anchor{117}
+@anchor{gnat_ugn/building_executable_programs_with_gnat binder-error-message-control}@anchor{116}@anchor{gnat_ugn/building_executable_programs_with_gnat id36}@anchor{117}
@subsubsection Binder Error Message Control
@@ -16189,7 +16189,7 @@ with extreme care.
@end table
@node Elaboration Control,Output Control,Binder Error Message Control,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id37}@anchor{118}@anchor{gnat_ugn/building_executable_programs_with_gnat elaboration-control}@anchor{111}
+@anchor{gnat_ugn/building_executable_programs_with_gnat elaboration-control}@anchor{111}@anchor{gnat_ugn/building_executable_programs_with_gnat id37}@anchor{118}
@subsubsection Elaboration Control
@@ -16205,10 +16205,10 @@ order. For further details see @ref{f,,Elaboration Order Handling in GNAT}.
Force elaboration order.
-@code{elab-order} should be the name of a "forced elaboration order file", that
+@code{elab-order} should be the name of a “forced elaboration order file”, that
is, a text file containing library item names, one per line. A name of the
-form "some.unit%s" or "some.unit (spec)" denotes the spec of Some.Unit. A
-name of the form "some.unit%b" or "some.unit (body)" denotes the body of
+form “some.unit%s” or “some.unit (spec)” denotes the spec of Some.Unit. A
+name of the form “some.unit%b” or “some.unit (body)” denotes the body of
Some.Unit. Each pair of lines is taken to mean that there is an elaboration
dependence of the second line on the first. For example, if the file
contains:
@@ -16229,11 +16229,11 @@ forcing the body of This to be elaborated before the spec of That.
The given order must be consistent with Ada rules, or else @code{gnatbind} will
give elaboration cycle errors. For example, if you say x (body) should be
elaborated before x (spec), there will be a cycle, because Ada rules require
-x (spec) to be elaborated before x (body); you can't have the spec and body
+x (spec) to be elaborated before x (body); you can’t have the spec and body
both elaborated before each other.
-If you later add "with That;" to the body of This, there will be a cycle, in
-which case you should erase either "this (body)" or "that (spec)" from the
+If you later add “with That;” to the body of This, there will be a cycle, in
+which case you should erase either “this (body)” or “that (spec)” from the
above forced elaboration order file.
Blank lines and Ada-style comments are ignored. Unit names that do not exist
@@ -16274,7 +16274,7 @@ debugging/experimental use.
@end table
@node Output Control,Dynamic Allocation Control,Elaboration Control,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat output-control}@anchor{119}@anchor{gnat_ugn/building_executable_programs_with_gnat id38}@anchor{11a}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id38}@anchor{119}@anchor{gnat_ugn/building_executable_programs_with_gnat output-control}@anchor{11a}
@subsubsection Output Control
@@ -16359,7 +16359,7 @@ be used to improve code generation in some cases.
@subsubsection Dynamic Allocation Control
-The heap control switches -- @code{-H32} and @code{-H64} --
+The heap control switches – @code{-H32} and @code{-H64} –
determine whether dynamic allocation uses 32-bit or 64-bit memory.
They only affect compiler-generated allocations via @code{__gnat_malloc};
explicit calls to @code{malloc} and related functions from the C
@@ -16508,7 +16508,7 @@ the binder switch
@end table
@node Command-Line Access,Search Paths for gnatbind,Switches for gnatbind,Binding with gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id42}@anchor{11f}@anchor{gnat_ugn/building_executable_programs_with_gnat command-line-access}@anchor{120}
+@anchor{gnat_ugn/building_executable_programs_with_gnat command-line-access}@anchor{11f}@anchor{gnat_ugn/building_executable_programs_with_gnat id42}@anchor{120}
@subsection Command-Line Access
@@ -16538,7 +16538,7 @@ required, your main program must set @code{gnat_argc} and
it.
@node Search Paths for gnatbind,Examples of gnatbind Usage,Command-Line Access,Binding with gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat search-paths-for-gnatbind}@anchor{76}@anchor{gnat_ugn/building_executable_programs_with_gnat id43}@anchor{121}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id43}@anchor{121}@anchor{gnat_ugn/building_executable_programs_with_gnat search-paths-for-gnatbind}@anchor{76}
@subsection Search Paths for @code{gnatbind}
@@ -16595,7 +16595,7 @@ of GNAT).
The content of the @code{ada_object_path} file which is part of the GNAT
installation tree and is used to store standard libraries such as the
GNAT Run-Time Library (RTL) unless the switch @code{-nostdlib} is
-specified. See @ref{71,,Installing a library}
+specified. See @ref{72,,Installing a library}
@end itemize
@geindex -I (gnatbind)
@@ -16642,7 +16642,7 @@ in compiling sources from multiple directories. This can make
development environments much more flexible.
@node Examples of gnatbind Usage,,Search Paths for gnatbind,Binding with gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id44}@anchor{122}@anchor{gnat_ugn/building_executable_programs_with_gnat examples-of-gnatbind-usage}@anchor{123}
+@anchor{gnat_ugn/building_executable_programs_with_gnat examples-of-gnatbind-usage}@anchor{122}@anchor{gnat_ugn/building_executable_programs_with_gnat id44}@anchor{123}
@subsection Examples of @code{gnatbind} Usage
@@ -16895,7 +16895,7 @@ for further details. You would normally use the @code{-b} or
@item @code{-M}
When linking an executable, create a map file. The name of the map file
-has the same name as the executable with extension ".map".
+has the same name as the executable with extension “.map”.
@end table
@geindex -M= (gnatlink)
@@ -16956,7 +16956,7 @@ switch.
@end table
@node Using the GNU make Utility,,Linking with gnatlink,Building Executable Programs with GNAT
-@anchor{gnat_ugn/building_executable_programs_with_gnat using-the-gnu-make-utility}@anchor{70}@anchor{gnat_ugn/building_executable_programs_with_gnat id48}@anchor{12b}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id48}@anchor{12b}@anchor{gnat_ugn/building_executable_programs_with_gnat using-the-gnu-make-utility}@anchor{70}
@section Using the GNU @code{make} Utility
@@ -16981,7 +16981,7 @@ is the same, these examples use some advanced features found only in
@end menu
@node Using gnatmake in a Makefile,Automatically Creating a List of Directories,,Using the GNU make Utility
-@anchor{gnat_ugn/building_executable_programs_with_gnat using-gnatmake-in-a-makefile}@anchor{12c}@anchor{gnat_ugn/building_executable_programs_with_gnat id49}@anchor{12d}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id49}@anchor{12c}@anchor{gnat_ugn/building_executable_programs_with_gnat using-gnatmake-in-a-makefile}@anchor{12d}
@subsection Using gnatmake in a Makefile
@@ -17080,7 +17080,7 @@ clean::
@end example
@node Automatically Creating a List of Directories,Generating the Command Line Switches,Using gnatmake in a Makefile,Using the GNU make Utility
-@anchor{gnat_ugn/building_executable_programs_with_gnat id50}@anchor{12f}@anchor{gnat_ugn/building_executable_programs_with_gnat automatically-creating-a-list-of-directories}@anchor{12e}
+@anchor{gnat_ugn/building_executable_programs_with_gnat automatically-creating-a-list-of-directories}@anchor{12e}@anchor{gnat_ugn/building_executable_programs_with_gnat id50}@anchor{12f}
@subsection Automatically Creating a List of Directories
@@ -17153,7 +17153,7 @@ DIRS := $@{shell find $@{ROOT_DIRECTORY@} -type d -print@}
@end example
@node Generating the Command Line Switches,Overcoming Command Line Length Limits,Automatically Creating a List of Directories,Using the GNU make Utility
-@anchor{gnat_ugn/building_executable_programs_with_gnat id51}@anchor{130}@anchor{gnat_ugn/building_executable_programs_with_gnat generating-the-command-line-switches}@anchor{131}
+@anchor{gnat_ugn/building_executable_programs_with_gnat generating-the-command-line-switches}@anchor{130}@anchor{gnat_ugn/building_executable_programs_with_gnat id51}@anchor{131}
@subsection Generating the Command Line Switches
@@ -17179,7 +17179,7 @@ all:
@end example
@node Overcoming Command Line Length Limits,,Generating the Command Line Switches,Using the GNU make Utility
-@anchor{gnat_ugn/building_executable_programs_with_gnat overcoming-command-line-length-limits}@anchor{132}@anchor{gnat_ugn/building_executable_programs_with_gnat id52}@anchor{133}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id52}@anchor{132}@anchor{gnat_ugn/building_executable_programs_with_gnat overcoming-command-line-length-limits}@anchor{133}
@subsection Overcoming Command Line Length Limits
@@ -17299,7 +17299,7 @@ generated files and executable files.
@end menu
@node Running gnatclean,Switches for gnatclean,,The File Cleanup Utility gnatclean
-@anchor{gnat_ugn/gnat_utility_programs running-gnatclean}@anchor{139}@anchor{gnat_ugn/gnat_utility_programs id3}@anchor{13a}
+@anchor{gnat_ugn/gnat_utility_programs id3}@anchor{139}@anchor{gnat_ugn/gnat_utility_programs running-gnatclean}@anchor{13a}
@subsection Running @code{gnatclean}
@@ -17525,7 +17525,7 @@ where @code{gnatclean} was invoked.
@end table
@node The GNAT Library Browser gnatls,,The File Cleanup Utility gnatclean,GNAT Utility Programs
-@anchor{gnat_ugn/gnat_utility_programs the-gnat-library-browser-gnatls}@anchor{137}@anchor{gnat_ugn/gnat_utility_programs id5}@anchor{13d}
+@anchor{gnat_ugn/gnat_utility_programs id5}@anchor{13d}@anchor{gnat_ugn/gnat_utility_programs the-gnat-library-browser-gnatls}@anchor{137}
@section The GNAT Library Browser @code{gnatls}
@@ -17741,7 +17741,7 @@ Several such switches may be specified simultaneously.
@item @code{-aO@emph{dir}}, @code{-aI@emph{dir}}, @code{-I@emph{dir}}, @code{-I-}, @code{-nostdinc}
Source path manipulation. Same meaning as the equivalent @code{gnatmake}
-flags (@ref{cd,,Switches for gnatmake}).
+flags (@ref{ce,,Switches for gnatmake}).
@end table
@geindex -aP (gnatls)
@@ -17762,7 +17762,7 @@ Add @code{dir} at the beginning of the project search dir.
@item @code{--RTS=@emph{rts-path}}
Specifies the default location of the runtime library. Same meaning as the
-equivalent @code{gnatmake} flag (@ref{cd,,Switches for gnatmake}).
+equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}).
@end table
@geindex -v (gnatls)
@@ -17808,7 +17808,7 @@ by the user.
@end table
@node Example of gnatls Usage,,Switches for gnatls,The GNAT Library Browser gnatls
-@anchor{gnat_ugn/gnat_utility_programs id8}@anchor{142}@anchor{gnat_ugn/gnat_utility_programs example-of-gnatls-usage}@anchor{143}
+@anchor{gnat_ugn/gnat_utility_programs example-of-gnatls-usage}@anchor{142}@anchor{gnat_ugn/gnat_utility_programs id8}@anchor{143}
@subsection Example of @code{gnatls} Usage
@@ -17897,7 +17897,7 @@ instr.ads
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node GNAT and Program Execution,Platform-Specific Information,GNAT Utility Programs,Top
-@anchor{gnat_ugn/gnat_and_program_execution gnat-and-program-execution}@anchor{c}@anchor{gnat_ugn/gnat_and_program_execution doc}@anchor{144}@anchor{gnat_ugn/gnat_and_program_execution id1}@anchor{145}
+@anchor{gnat_ugn/gnat_and_program_execution doc}@anchor{144}@anchor{gnat_ugn/gnat_and_program_execution gnat-and-program-execution}@anchor{c}@anchor{gnat_ugn/gnat_and_program_execution id1}@anchor{145}
@chapter GNAT and Program Execution
@@ -17994,7 +17994,7 @@ the incorrect user program.
@end menu
@node The GNAT Debugger GDB,Running GDB,,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debugger-gdb}@anchor{14e}@anchor{gnat_ugn/gnat_and_program_execution id3}@anchor{14f}
+@anchor{gnat_ugn/gnat_and_program_execution id3}@anchor{14e}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debugger-gdb}@anchor{14f}
@subsection The GNAT Debugger GDB
@@ -18078,7 +18078,7 @@ exactly as if the debugger were not present. The following section
describes some of the additional commands that can be given to @code{GDB}.
@node Introduction to GDB Commands,Using Ada Expressions,Running GDB,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution introduction-to-gdb-commands}@anchor{152}@anchor{gnat_ugn/gnat_and_program_execution id5}@anchor{153}
+@anchor{gnat_ugn/gnat_and_program_execution id5}@anchor{152}@anchor{gnat_ugn/gnat_and_program_execution introduction-to-gdb-commands}@anchor{153}
@subsection Introduction to GDB Commands
@@ -18319,12 +18319,12 @@ Thus, for brevity, the debugger acts as if there were
implicit @code{with} and @code{use} clauses in effect for all user-written
packages, thus making it unnecessary to fully qualify most names with
their packages, regardless of context. Where this causes ambiguity,
-@code{GDB} asks the user's intent.
+@code{GDB} asks the user’s intent.
For details on the supported Ada syntax, see @cite{Debugging with GDB}.
@node Calling User-Defined Subprograms,Using the next Command in a Function,Using Ada Expressions,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution id7}@anchor{156}@anchor{gnat_ugn/gnat_and_program_execution calling-user-defined-subprograms}@anchor{157}
+@anchor{gnat_ugn/gnat_and_program_execution calling-user-defined-subprograms}@anchor{156}@anchor{gnat_ugn/gnat_and_program_execution id7}@anchor{157}
@subsection Calling User-Defined Subprograms
@@ -18383,7 +18383,7 @@ elements directly from GDB, you can write a callable procedure that prints
the elements in the desired format.
@node Using the next Command in a Function,Stopping When Ada Exceptions Are Raised,Calling User-Defined Subprograms,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution using-the-next-command-in-a-function}@anchor{158}@anchor{gnat_ugn/gnat_and_program_execution id8}@anchor{159}
+@anchor{gnat_ugn/gnat_and_program_execution id8}@anchor{158}@anchor{gnat_ugn/gnat_and_program_execution using-the-next-command-in-a-function}@anchor{159}
@subsection Using the @emph{next} Command in a Function
@@ -18391,7 +18391,7 @@ When you use the @code{next} command in a function, the current source
location will advance to the next statement as usual. A special case
arises in the case of a @code{return} statement.
-Part of the code for a return statement is the 'epilogue' of the function.
+Part of the code for a return statement is the ‘epilogue’ of the function.
This is the code that returns to the caller. There is only one copy of
this epilogue code, and it is typically associated with the last return
statement in the function if there is more than one return. In some
@@ -18406,7 +18406,7 @@ The value returned is always that from the first return statement
that was stepped through.
@node Stopping When Ada Exceptions Are Raised,Ada Tasks,Using the next Command in a Function,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution stopping-when-ada-exceptions-are-raised}@anchor{15a}@anchor{gnat_ugn/gnat_and_program_execution id9}@anchor{15b}
+@anchor{gnat_ugn/gnat_and_program_execution id9}@anchor{15a}@anchor{gnat_ugn/gnat_and_program_execution stopping-when-ada-exceptions-are-raised}@anchor{15b}
@subsection Stopping When Ada Exceptions Are Raised
@@ -18501,7 +18501,7 @@ to refer to tasks in the following commands.
@itemize *
@item
-@code{break`@w{`}*linespec* `@w{`}task} @emph{taskid}, @code{break} @emph{linespec} @code{task} @emph{taskid} @code{if} ...
+@code{break`@w{`}*linespec* `@w{`}task} @emph{taskid}, @code{break} @emph{linespec} @code{task} @emph{taskid} @code{if} …
@quotation
@@ -18609,7 +18609,7 @@ other units.
@geindex Remote Debugging with gdbserver
@node Remote Debugging with gdbserver,GNAT Abnormal Termination or Failure to Terminate,Debugging Generic Units,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution remote-debugging-with-gdbserver}@anchor{160}@anchor{gnat_ugn/gnat_and_program_execution id12}@anchor{161}
+@anchor{gnat_ugn/gnat_and_program_execution id12}@anchor{160}@anchor{gnat_ugn/gnat_and_program_execution remote-debugging-with-gdbserver}@anchor{161}
@subsection Remote Debugging with gdbserver
@@ -18722,7 +18722,7 @@ Finally, you can start
@code{gdb} directly on the @code{gnat1} executable. @code{gnat1} is the
front-end of GNAT, and can be run independently (normally it is just
called from @code{gcc}). You can use @code{gdb} on @code{gnat1} as you
-would on a C program (but @ref{14e,,The GNAT Debugger GDB} for caveats). The
+would on a C program (but @ref{14f,,The GNAT Debugger GDB} for caveats). The
@code{where} command is the first line of attack; the variable
@code{lineno} (seen by @code{print lineno}), used by the second phase of
@code{gnat1} and by the @code{gcc} backend, indicates the source line at
@@ -18731,7 +18731,7 @@ the source file.
@end itemize
@node Naming Conventions for GNAT Source Files,Getting Internal Debugging Information,GNAT Abnormal Termination or Failure to Terminate,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution naming-conventions-for-gnat-source-files}@anchor{164}@anchor{gnat_ugn/gnat_and_program_execution id14}@anchor{165}
+@anchor{gnat_ugn/gnat_and_program_execution id14}@anchor{164}@anchor{gnat_ugn/gnat_and_program_execution naming-conventions-for-gnat-source-files}@anchor{165}
@subsection Naming Conventions for GNAT Source Files
@@ -18812,7 +18812,7 @@ the other @code{.c} files are modifications of common @code{gcc} files.
@end itemize
@node Getting Internal Debugging Information,Stack Traceback,Naming Conventions for GNAT Source Files,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution id15}@anchor{166}@anchor{gnat_ugn/gnat_and_program_execution getting-internal-debugging-information}@anchor{167}
+@anchor{gnat_ugn/gnat_and_program_execution getting-internal-debugging-information}@anchor{166}@anchor{gnat_ugn/gnat_and_program_execution id15}@anchor{167}
@subsection Getting Internal Debugging Information
@@ -18840,7 +18840,7 @@ are replaced with run-time calls.
@geindex stack unwinding
@node Stack Traceback,Pretty-Printers for the GNAT runtime,Getting Internal Debugging Information,Running and Debugging Ada Programs
-@anchor{gnat_ugn/gnat_and_program_execution stack-traceback}@anchor{168}@anchor{gnat_ugn/gnat_and_program_execution id16}@anchor{169}
+@anchor{gnat_ugn/gnat_and_program_execution id16}@anchor{168}@anchor{gnat_ugn/gnat_and_program_execution stack-traceback}@anchor{169}
@subsection Stack Traceback
@@ -18869,7 +18869,7 @@ is enabled, and no exception is raised during program execution.
@end menu
@node Non-Symbolic Traceback,Symbolic Traceback,,Stack Traceback
-@anchor{gnat_ugn/gnat_and_program_execution non-symbolic-traceback}@anchor{16a}@anchor{gnat_ugn/gnat_and_program_execution id17}@anchor{16b}
+@anchor{gnat_ugn/gnat_and_program_execution id17}@anchor{16a}@anchor{gnat_ugn/gnat_and_program_execution non-symbolic-traceback}@anchor{16b}
@subsubsection Non-Symbolic Traceback
@@ -18996,7 +18996,7 @@ From this traceback we can see that the exception was raised in
@code{stb.adb} at line 5, which was reached from a procedure call in
@code{stb.adb} at line 10, and so on. The @code{b~std.adb} is the binder file,
which contains the call to the main program.
-@ref{10d,,Running gnatbind}. The remaining entries are assorted runtime routines,
+@ref{10e,,Running gnatbind}. The remaining entries are assorted runtime routines,
and the output will vary from platform to platform.
It is also possible to use @code{GDB} with these traceback addresses to debug
@@ -19148,7 +19148,7 @@ In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
You can then get further information by invoking the @code{addr2line}
tool as described earlier (note that the hexadecimal addresses
-need to be specified in C format, with a leading '0x').
+need to be specified in C format, with a leading ‘0x’).
@geindex traceback
@geindex symbolic
@@ -19286,7 +19286,7 @@ program.
@subsection Pretty-Printers for the GNAT runtime
-As discussed in @cite{Calling User-Defined Subprograms}, GDB's
+As discussed in @cite{Calling User-Defined Subprograms}, GDB’s
@code{print} command only knows about the physical layout of program data
structures and therefore normally displays only low-level dumps, which
are often hard to understand.
@@ -19351,7 +19351,7 @@ python import gnatdbg; gnatdbg.setup()
@end example
@end quotation
-Once this is done, GDB's @code{print} command will automatically use
+Once this is done, GDB’s @code{print} command will automatically use
these pretty-printers when appropriate. Using the previous example:
@quotation
@@ -19368,8 +19368,8 @@ $1 = pp.int_to_nat.map of length 3 = @{
Pretty-printers are invoked each time GDB tries to display a value,
including when displaying the arguments of a called subprogram (in
-GDB's @code{backtrace} command) or when printing the value returned by a
-function (in GDB's @code{finish} command).
+GDB’s @code{backtrace} command) or when printing the value returned by a
+function (in GDB’s @code{finish} command).
To display a value without involving pretty-printers, @code{print} can be
invoked with its @code{/r} option:
@@ -19389,7 +19389,7 @@ for more information.
@geindex Profiling
@node Profiling,Improving Performance,Running and Debugging Ada Programs,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution profiling}@anchor{147}@anchor{gnat_ugn/gnat_and_program_execution id20}@anchor{170}
+@anchor{gnat_ugn/gnat_and_program_execution id20}@anchor{170}@anchor{gnat_ugn/gnat_and_program_execution profiling}@anchor{147}
@section Profiling
@@ -19410,7 +19410,7 @@ This section describes how to use the @code{gprof} profiler tool on Ada programs
This section is not meant to be an exhaustive documentation of @code{gprof}.
-Full documentation for it can be found in the @cite{GNU Profiler User's Guide}
+Full documentation for it can be found in the @cite{GNU Profiler User’s Guide}
documentation that is part of this GNAT distribution.
Profiling a program helps determine the parts of a program that are executed
@@ -19459,7 +19459,7 @@ to interpret the results.
@end menu
@node Compilation for profiling,Program execution,,Profiling an Ada Program with gprof
-@anchor{gnat_ugn/gnat_and_program_execution id22}@anchor{173}@anchor{gnat_ugn/gnat_and_program_execution compilation-for-profiling}@anchor{174}
+@anchor{gnat_ugn/gnat_and_program_execution compilation-for-profiling}@anchor{173}@anchor{gnat_ugn/gnat_and_program_execution id22}@anchor{174}
@subsubsection Compilation for profiling
@@ -19487,7 +19487,7 @@ be profiled; if you need to profile your whole project, use the @code{-f}
gnatmake switch to force full recompilation.
@node Program execution,Running gprof,Compilation for profiling,Profiling an Ada Program with gprof
-@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{175}@anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{176}
+@anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{175}@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{176}
@subsubsection Program execution
@@ -19502,7 +19502,7 @@ generated in the directory where the program was launched from. If this file
already exists, it will be overwritten.
@node Running gprof,Interpretation of profiling results,Program execution,Profiling an Ada Program with gprof
-@anchor{gnat_ugn/gnat_and_program_execution running-gprof}@anchor{177}@anchor{gnat_ugn/gnat_and_program_execution id24}@anchor{178}
+@anchor{gnat_ugn/gnat_and_program_execution id24}@anchor{177}@anchor{gnat_ugn/gnat_and_program_execution running-gprof}@anchor{178}
@subsubsection Running gprof
@@ -19535,7 +19535,7 @@ $ gprof [switches] [executable [data-file]]
@code{gprof} supports numerous switches. The order of these
switch does not matter. The full list of options can be found in
-the GNU Profiler User's Guide documentation that comes with this documentation.
+the GNU Profiler User’s Guide documentation that comes with this documentation.
The following is the subset of those switches that is most relevant:
@@ -19564,7 +19564,7 @@ compiler, in particular Ada symbols generated by GNAT can be demangled using
The @code{-e @emph{function}} option tells @code{gprof} not to print
information about the function @code{function_name} (and its
-children...) in the call graph. The function will still be listed
+children…) in the call graph. The function will still be listed
as a child of any functions that call it, but its index number will be
shown as @code{[not printed]}. More than one @code{-e} option may be
given; only one @code{function_name} may be indicated with each @code{-e}
@@ -19594,7 +19594,7 @@ the call graph. More than one @code{-E} option may be given; only one
The @code{-f @emph{function}} option causes @code{gprof} to limit the
call graph to the function @code{function_name} and its children (and
-their children...). More than one @code{-f} option may be given;
+their children…). More than one @code{-f} option may be given;
only one @code{function_name} may be indicated with each @code{-f}
option.
@end table
@@ -19608,7 +19608,7 @@ option.
The @code{-F @emph{function}} option works like the @code{-f} option, but
only time spent in the function and its children (and their
-children...) will be used to determine total-time and
+children…) will be used to determine total-time and
percentages-of-time for the call graph. More than one @code{-F} option
may be given; only one @code{function_name} may be indicated with each
@code{-F} option. The @code{-F} option overrides the @code{-E} option.
@@ -19620,8 +19620,8 @@ may be given; only one @code{function_name} may be indicated with each
The results of the profiling analysis are represented by two arrays: the
-'flat profile' and the 'call graph'. Full documentation of those outputs
-can be found in the GNU Profiler User's Guide.
+‘flat profile’ and the ‘call graph’. Full documentation of those outputs
+can be found in the GNU Profiler User’s Guide.
The flat profile shows the time spent in each function of the program, and how
many time it has been called. This allows you to locate easily the most
@@ -19632,7 +19632,7 @@ and the subprograms that it calls. It also provides an estimate of the time
spent in each of those callers/called subprograms.
@node Improving Performance,Overflow Check Handling in GNAT,Profiling,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution improving-performance}@anchor{17b}@anchor{gnat_ugn/gnat_and_program_execution id26}@anchor{148}
+@anchor{gnat_ugn/gnat_and_program_execution id26}@anchor{148}@anchor{gnat_ugn/gnat_and_program_execution improving-performance}@anchor{17b}
@section Improving Performance
@@ -19653,7 +19653,7 @@ which can reduce the size of program executables.
@end menu
@node Performance Considerations,Text_IO Suggestions,,Improving Performance
-@anchor{gnat_ugn/gnat_and_program_execution performance-considerations}@anchor{17c}@anchor{gnat_ugn/gnat_and_program_execution id27}@anchor{17d}
+@anchor{gnat_ugn/gnat_and_program_execution id27}@anchor{17c}@anchor{gnat_ugn/gnat_and_program_execution performance-considerations}@anchor{17d}
@subsection Performance Considerations
@@ -19714,7 +19714,7 @@ some guidelines on debugging optimized code.
@end menu
@node Controlling Run-Time Checks,Use of Restrictions,,Performance Considerations
-@anchor{gnat_ugn/gnat_and_program_execution id28}@anchor{17e}@anchor{gnat_ugn/gnat_and_program_execution controlling-run-time-checks}@anchor{17f}
+@anchor{gnat_ugn/gnat_and_program_execution controlling-run-time-checks}@anchor{17e}@anchor{gnat_ugn/gnat_and_program_execution id28}@anchor{17f}
@subsubsection Controlling Run-Time Checks
@@ -19808,7 +19808,7 @@ possibility of an immediate abort at any point.
@geindex -O (gcc)
Without any optimization option,
-the compiler's goal is to reduce the cost of
+the compiler’s goal is to reduce the cost of
compilation and to make debugging produce the expected results.
Statements are independent: if you stop the program with a breakpoint between
statements, you can then assign a new value to any variable or change
@@ -19845,7 +19845,7 @@ generates unoptimized code but has
the fastest compilation time.
Note that many other compilers do substantial optimization even
-if 'no optimization' is specified. With gcc, it is very unusual
+if ‘no optimization’ is specified. With gcc, it is very unusual
to use @code{-O0} for production if execution time is of any concern,
since @code{-O0} means (almost) no optimization. This difference
between gcc and other compilers should be kept in mind when
@@ -19963,7 +19963,7 @@ These are the most common cases:
@itemize *
@item
-@emph{The 'hopping Program Counter':} Repeated @code{step} or @code{next}
+@emph{The ‘hopping Program Counter’:} Repeated @code{step} or @code{next}
commands show
the PC bouncing back and forth in the code. This may result from any of
the following optimizations:
@@ -19992,7 +19992,7 @@ expected side-effects.
@end itemize
@item
-@emph{The 'big leap':} More commonly known as @emph{cross-jumping}, in which
+@emph{The ‘big leap’:} More commonly known as @emph{cross-jumping}, in which
two identical pieces of code are merged and the program counter suddenly
jumps to a statement that is not supposed to be executed, simply because
it (and the code following) translates to the same thing as the code
@@ -20001,7 +20001,7 @@ sequences that end in a jump, such as a @code{goto}, a @code{return}, or
a @code{break} in a C @code{switch} statement.
@item
-@emph{The 'roving variable':} The symptom is an unexpected value in a variable.
+@emph{The ‘roving variable’:} The symptom is an unexpected value in a variable.
There are various reasons for this effect:
@@ -20009,7 +20009,7 @@ There are various reasons for this effect:
@item
In a subprogram prologue, a parameter may not yet have been moved to its
-'home'.
+‘home’.
@item
A variable may be dead, and its register re-used. This is
@@ -20038,7 +20038,7 @@ values (one must apply the procedure recursively to those
other values); or re-running the code and stopping a little earlier
(perhaps before the call) and stepping to better see how the variable obtained
the value in question; or continuing to step @emph{from} the point of the
-strange value to see if code motion had simply moved the variable's
+strange value to see if code motion had simply moved the variable’s
assignments later.
@end itemize
@@ -20254,7 +20254,7 @@ by default at this level, using @code{-O3} directly is recommended.
You also need to make sure that the target architecture features a supported
SIMD instruction set. For example, for the x86 architecture, you should at
-least specify @code{-msse2} to get significant vectorization (but you don't
+least specify @code{-msse2} to get significant vectorization (but you don’t
need to specify it for x86-64 as it is part of the base 64-bit architecture).
Similarly, for the PowerPC architecture, you should specify @code{-maltivec}.
@@ -20391,7 +20391,7 @@ placed immediately within the loop will tell the compiler that it can safely
omit the non-vectorized version of the loop as well as the run-time test.
@node Other Optimization Switches,Optimization and Strict Aliasing,Vectorization of loops,Performance Considerations
-@anchor{gnat_ugn/gnat_and_program_execution other-optimization-switches}@anchor{18a}@anchor{gnat_ugn/gnat_and_program_execution id35}@anchor{18b}
+@anchor{gnat_ugn/gnat_and_program_execution id35}@anchor{18a}@anchor{gnat_ugn/gnat_and_program_execution other-optimization-switches}@anchor{18b}
@subsubsection Other Optimization Switches
@@ -20408,7 +20408,7 @@ the @emph{Submodel Options} section in the @emph{Hardware Models and Configurati
chapter of @cite{Using the GNU Compiler Collection (GCC)}.
@node Optimization and Strict Aliasing,Aliased Variables and Optimization,Other Optimization Switches,Performance Considerations
-@anchor{gnat_ugn/gnat_and_program_execution optimization-and-strict-aliasing}@anchor{e4}@anchor{gnat_ugn/gnat_and_program_execution id36}@anchor{18c}
+@anchor{gnat_ugn/gnat_and_program_execution id36}@anchor{18c}@anchor{gnat_ugn/gnat_and_program_execution optimization-and-strict-aliasing}@anchor{e4}
@subsubsection Optimization and Strict Aliasing
@@ -20451,7 +20451,7 @@ In this example, since the variable @code{Int1V} can only access objects
of type @code{Int1}, and @code{Int2V} can only access objects of type
@code{Int2}, there is no possibility that the assignment to
@code{Int2V.all} affects the value of @code{Int1V.all}. This means that
-the compiler optimizer can "know" that the value @code{Int1V.all} is constant
+the compiler optimizer can “know” that the value @code{Int1V.all} is constant
for all iterations of the loop and avoid the extra memory reference
required to dereference it each time through the loop.
@@ -20505,7 +20505,7 @@ end;
@end quotation
This program prints out 0 in @code{-O0} or @code{-O1}
-mode, but it prints out 1 in @code{-O2} mode. That's
+mode, but it prints out 1 in @code{-O2} mode. That’s
because in strict aliasing mode, the compiler can and
does assume that the assignment to @code{v2.all} could not
affect the value of @code{v1.all}, since different types
@@ -20515,7 +20515,7 @@ This behavior is not a case of non-conformance with the standard, since
the Ada RM specifies that an unchecked conversion where the resulting
bit pattern is not a correct value of the target type can result in an
abnormal value and attempting to reference an abnormal value makes the
-execution of a program erroneous. That's the case here since the result
+execution of a program erroneous. That’s the case here since the result
does not point to an object of type @code{int2}. This means that the
effect is entirely unpredictable.
@@ -20538,7 +20538,7 @@ p2.adb:5:07: warning: or use "pragma No_Strict_Aliasing (a2);"
@end quotation
Unfortunately the problem is recognized when compiling the body of
-package @code{p2}, but the actual "bad" code is generated while
+package @code{p2}, but the actual “bad” code is generated while
compiling the body of @code{m} and this latter compilation does not see
the suspicious @code{Unchecked_Conversion}.
@@ -20559,7 +20559,7 @@ the switch can be painful, so a more reasonable approach
is to compile the entire program with options @code{-O2}
and @code{-fno-strict-aliasing}. If the performance is
satisfactory with this combination of options, then the
-advantage is that the entire issue of possible "wrong"
+advantage is that the entire issue of possible “wrong”
optimization due to strict aliasing is avoided.
To avoid the use of compiler switches, the configuration
@@ -20597,7 +20597,7 @@ conversion to the unit in which the type is declared. In
this example, we would move the instantiation of
@code{Unchecked_Conversion} from the body of package
@code{p2} to the spec of package @code{p1}. Now the
-warning disappears. That's because any use of the
+warning disappears. That’s because any use of the
access type knows there is a suspicious unchecked
conversion, and the strict aliasing optimization
is automatically suppressed for the type.
@@ -20638,7 +20638,7 @@ application code where the time is increased by up to 5% by turning
this optimization off. If you have code that includes significant
usage of unchecked conversion, you might want to just stick with
@code{-O1} and avoid the entire issue. If you get adequate
-performance at this level of optimization level, that's probably
+performance at this level of optimization level, that’s probably
the safest approach. If tests show that you really need higher
levels of optimization, then you can experiment with @code{-O2}
and @code{-O2 -fno-strict-aliasing} to see how much effect this
@@ -20648,7 +20648,7 @@ review any uses of unchecked conversion of access types,
particularly if you are getting the warnings described above.
@node Aliased Variables and Optimization,Atomic Variables and Optimization,Optimization and Strict Aliasing,Performance Considerations
-@anchor{gnat_ugn/gnat_and_program_execution id37}@anchor{18d}@anchor{gnat_ugn/gnat_and_program_execution aliased-variables-and-optimization}@anchor{18e}
+@anchor{gnat_ugn/gnat_and_program_execution aliased-variables-and-optimization}@anchor{18d}@anchor{gnat_ugn/gnat_and_program_execution id37}@anchor{18e}
@subsubsection Aliased Variables and Optimization
@@ -20659,7 +20659,7 @@ use low level techniques to modify variables
that otherwise might be considered to be unassigned. For example,
a variable can be passed to a procedure by reference, which takes
the address of the parameter and uses the address to modify the
-variable's value, even though it is passed as an IN parameter.
+variable’s value, even though it is passed as an IN parameter.
Consider the following example:
@quotation
@@ -20699,10 +20699,10 @@ seems to work with no optimization to start failing at high
levels of optimzization.
What the compiler does for such cases is to assume that marking
-a variable as aliased indicates that some "funny business" may
+a variable as aliased indicates that some “funny business” may
be going on. The optimizer recognizes the aliased keyword and
inhibits optimizations that assume the value cannot be assigned.
-This means that the above example will in fact "work" reliably,
+This means that the above example will in fact “work” reliably,
that is, it will produce the expected results.
@node Atomic Variables and Optimization,Passive Task Optimization,Aliased Variables and Optimization,Performance Considerations
@@ -20773,7 +20773,7 @@ Now the reference to RV must read the whole variable.
Actually one can imagine some compiler which figures
out that the whole copy is not required (because only
the B field is actually accessed), but GNAT
-certainly won't do that, and we don't know of any
+certainly won’t do that, and we don’t know of any
compiler that would not handle this right, and the
above code will in practice work portably across
all architectures (that permit the Atomic declaration).
@@ -20787,7 +20787,7 @@ such synchronization code is not required, it may be
useful to disable it.
@node Passive Task Optimization,,Atomic Variables and Optimization,Performance Considerations
-@anchor{gnat_ugn/gnat_and_program_execution passive-task-optimization}@anchor{191}@anchor{gnat_ugn/gnat_and_program_execution id39}@anchor{192}
+@anchor{gnat_ugn/gnat_and_program_execution id39}@anchor{191}@anchor{gnat_ugn/gnat_and_program_execution passive-task-optimization}@anchor{192}
@subsubsection Passive Task Optimization
@@ -20811,7 +20811,7 @@ operations will be optimized, and furthermore this optimized
performance is fully portable.
Although it would theoretically be possible for GNAT to attempt to
-do this optimization, but it really doesn't make sense in the
+do this optimization, but it really doesn’t make sense in the
context of Ada 95, and none of the Ada 95 compilers implement
this optimization as far as we know. In particular GNAT never
attempts to perform this optimization.
@@ -20832,7 +20832,7 @@ that typically clients of the tasks who call entries, will not have
to be modified, only the task definition itself.
@node Text_IO Suggestions,Reducing Size of Executables with Unused Subprogram/Data Elimination,Performance Considerations,Improving Performance
-@anchor{gnat_ugn/gnat_and_program_execution text-io-suggestions}@anchor{193}@anchor{gnat_ugn/gnat_and_program_execution id40}@anchor{194}
+@anchor{gnat_ugn/gnat_and_program_execution id40}@anchor{193}@anchor{gnat_ugn/gnat_and_program_execution text-io-suggestions}@anchor{194}
@subsection @code{Text_IO} Suggestions
@@ -20872,7 +20872,7 @@ your executable just by setting options at compilation time.
@end menu
@node About unused subprogram/data elimination,Compilation options,,Reducing Size of Executables with Unused Subprogram/Data Elimination
-@anchor{gnat_ugn/gnat_and_program_execution id42}@anchor{197}@anchor{gnat_ugn/gnat_and_program_execution about-unused-subprogram-data-elimination}@anchor{198}
+@anchor{gnat_ugn/gnat_and_program_execution about-unused-subprogram-data-elimination}@anchor{197}@anchor{gnat_ugn/gnat_and_program_execution id42}@anchor{198}
@subsubsection About unused subprogram/data elimination
@@ -20888,7 +20888,7 @@ architecture and on all cross platforms using the ELF binary file format.
In both cases GNU binutils version 2.16 or later are required to enable it.
@node Compilation options,Example of unused subprogram/data elimination,About unused subprogram/data elimination,Reducing Size of Executables with Unused Subprogram/Data Elimination
-@anchor{gnat_ugn/gnat_and_program_execution id43}@anchor{199}@anchor{gnat_ugn/gnat_and_program_execution compilation-options}@anchor{19a}
+@anchor{gnat_ugn/gnat_and_program_execution compilation-options}@anchor{199}@anchor{gnat_ugn/gnat_and_program_execution id43}@anchor{19a}
@subsubsection Compilation options
@@ -21013,7 +21013,7 @@ This section explains how to control the handling of overflow checks.
@end menu
@node Background,Management of Overflows in GNAT,,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{19e}@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{19f}
+@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{19e}@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{19f}
@subsection Background
@@ -21090,7 +21090,7 @@ and then the application is moved to a compiler where the check is
performed on the intermediate result and an unexpected exception is
raised.
-Furthermore, when using Ada 2012's preconditions and other
+Furthermore, when using Ada 2012’s preconditions and other
assertion forms, another issue arises. Consider:
@quotation
@@ -21148,7 +21148,7 @@ mathematical versus run-time interpretation of the expressions in
assertions, GNAT provides comprehensive control over the handling
of intermediate overflow. GNAT can operate in three modes, and
furthemore, permits separate selection of operating modes for
-the expressions within assertions (here the term 'assertions'
+the expressions within assertions (here the term ‘assertions’
is used in the technical sense, which includes preconditions and so forth)
and for expressions appearing outside assertions.
@@ -21253,7 +21253,7 @@ out in the normal manner (with infinite values always failing all
range checks).
@node Specifying the Desired Mode,Default Settings,Management of Overflows in GNAT,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{e9}@anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1a2}
+@anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1a2}@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{e9}
@subsection Specifying the Desired Mode
@@ -21302,8 +21302,8 @@ pragma Overflow_Mode
@end quotation
specifies that general expressions outside assertions be evaluated
-in 'minimize intermediate overflows' mode, and expressions within
-assertions be evaluated in 'eliminate intermediate overflows' mode.
+in ‘minimize intermediate overflows’ mode, and expressions within
+assertions be evaluated in ‘eliminate intermediate overflows’ mode.
This is often a reasonable choice, avoiding excessive overhead
outside assertions, but assuring a high degree of portability
when importing code from another compiler, while incurring
@@ -21377,7 +21377,7 @@ causing all intermediate operations to be computed using the base
type (@code{STRICT} mode).
@node Default Settings,Implementation Notes,Specifying the Desired Mode,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1a3}@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1a4}
+@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1a3}@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1a4}
@subsection Default Settings
@@ -21424,7 +21424,7 @@ checking, but it has no effect on the method used for computing
intermediate results.
@node Implementation Notes,,Default Settings,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1a5}@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1a6}
+@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1a5}@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1a6}
@subsection Implementation Notes
@@ -21472,7 +21472,7 @@ platforms for which @code{Long_Long_Integer} is 64-bits (nearly all GNAT
platforms).
@node Performing Dimensionality Analysis in GNAT,Stack Related Facilities,Overflow Check Handling in GNAT,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{1a7}@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{14a}
+@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{14a}@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{1a7}
@section Performing Dimensionality Analysis in GNAT
@@ -21706,7 +21706,7 @@ aspect.
@end quotation
The @code{Dimension} aspect of a dimensioned subtype @code{S} defines a mapping
-from the base type's Unit_Names to integer (or, more generally, rational)
+from the base type’s Unit_Names to integer (or, more generally, rational)
values. This mapping is the @emph{dimension vector} (also referred to as the
@emph{dimensionality}) for that subtype, denoted by @code{DV(S)}, and thus for each
object of that subtype. Intuitively, the value specified for each
@@ -21749,7 +21749,7 @@ then @emph{expr} is dimensionless; @code{DV(@emph{expr})} is the empty vector.
@code{DV(@emph{op expr})}, where @emph{op} is a unary operator, is @code{DV(@emph{expr})}
@item
-@code{DV(@emph{expr1 op expr2})} where @emph{op} is "+" or "-" is @code{DV(@emph{expr1})}
+@code{DV(@emph{expr1 op expr2})} where @emph{op} is “+” or “-” is @code{DV(@emph{expr1})}
provided that @code{DV(@emph{expr1})} = @code{DV(@emph{expr2})}.
If this condition is not met then the construct is illegal.
@@ -21765,13 +21765,13 @@ provided that @emph{power} is a static rational value. If this condition is not
met then the construct is illegal.
@end itemize
-Note that, by the above rules, it is illegal to use binary "+" or "-" to
+Note that, by the above rules, it is illegal to use binary “+” or “-” to
combine a dimensioned and dimensionless value. Thus an expression such as
@code{acc-10.0} is illegal, where @code{acc} is an object of subtype
@code{Acceleration}.
The dimensionality checks for relationals use the same rules as
-for "+" and "-", except when comparing to a literal; thus
+for “+” and “-“, except when comparing to a literal; thus
@quotation
@@ -21826,7 +21826,7 @@ converted, for example, to a mass in pounds.
If @code{T} is the base type for @emph{expr} (and the dimensionless root type of
the dimension system), then @code{DV(T(@emph{expr}))} is @code{DV(expr)}.
Thus, if @emph{expr} is of a dimensioned subtype of @code{T}, the conversion may
-be regarded as a "view conversion" that preserves dimensionality.
+be regarded as a “view conversion” that preserves dimensionality.
This rule makes it possible to write generic code that can be instantiated
with compatible dimensioned subtypes. The generic unit will contain
@@ -21859,7 +21859,7 @@ passing (the dimension vector for the actual parameter must be equal to the
dimension vector for the formal parameter).
@node Stack Related Facilities,Memory Management Issues,Performing Dimensionality Analysis in GNAT,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{1a8}@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{14b}
+@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{14b}@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{1a8}
@section Stack Related Facilities
@@ -21889,7 +21889,7 @@ some other task exceeds the available stack space, then unpredictable
behavior will occur. Most native systems offer some level of protection by
adding a guard page at the end of each task stack. This mechanism is usually
not enough for dealing properly with stack overflow situations because
-a large local variable could "jump" above the guard page.
+a large local variable could “jump” above the guard page.
Furthermore, when the
guard page is hit, there may not be any space left on the stack for executing
the exception propagation code. Enabling stack checking avoids
@@ -21969,7 +21969,7 @@ subprogram whose stack usage might be larger than the specified amount of
bytes. The wording is in keeping with the qualifier documented above.
@node Dynamic Stack Usage Analysis,,Static Stack Usage Analysis,Stack Related Facilities
-@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1ab}@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{113}
+@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{113}@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1ab}
@subsection Dynamic Stack Usage Analysis
@@ -22028,7 +22028,7 @@ where:
@item
@emph{Stack Usage} is the measure done by the stack analyzer.
In order to prevent overflow, the stack
-is not entirely analyzed, and it's not possible to know exactly how
+is not entirely analyzed, and it’s not possible to know exactly how
much has actually been used.
@end itemize
@@ -22057,7 +22057,7 @@ stack-usage reports at run time. See its body for the details.
This section describes some useful memory pools provided in the GNAT library
and in particular the GNAT Debug Pool facility, which can be used to detect
-incorrect uses of access values (including 'dangling references').
+incorrect uses of access values (including ‘dangling references’).
@menu
@@ -22311,7 +22311,7 @@ Debug Pool info:
@c -- E.g. Ada |nbsp| 95
@node Platform-Specific Information,Example of Binder Output File,GNAT and Program Execution,Top
-@anchor{gnat_ugn/platform_specific_information platform-specific-information}@anchor{d}@anchor{gnat_ugn/platform_specific_information doc}@anchor{1b1}@anchor{gnat_ugn/platform_specific_information id1}@anchor{1b2}
+@anchor{gnat_ugn/platform_specific_information doc}@anchor{1b1}@anchor{gnat_ugn/platform_specific_information id1}@anchor{1b2}@anchor{gnat_ugn/platform_specific_information platform-specific-information}@anchor{d}
@chapter Platform-Specific Information
@@ -22357,7 +22357,7 @@ For exception handling, either or both of two models are supplied:
@itemize *
@item
-@strong{Zero-Cost Exceptions} ("ZCX"),
+@strong{Zero-Cost Exceptions} (“ZCX”),
which uses binder-generated tables that
are interrogated at run time to locate a handler.
@@ -22366,7 +22366,7 @@ are interrogated at run time to locate a handler.
@geindex SJLJ (setjmp/longjmp Exception Model)
@item
-@strong{setjmp / longjmp} ('SJLJ'),
+@strong{setjmp / longjmp} (‘SJLJ’),
which uses dynamically-set data to establish
the set of handlers
@end itemize
@@ -22390,7 +22390,7 @@ are supplied on various GNAT platforms.
@end menu
@node Summary of Run-Time Configurations,,,Run-Time Libraries
-@anchor{gnat_ugn/platform_specific_information summary-of-run-time-configurations}@anchor{1b5}@anchor{gnat_ugn/platform_specific_information id3}@anchor{1b6}
+@anchor{gnat_ugn/platform_specific_information id3}@anchor{1b5}@anchor{gnat_ugn/platform_specific_information summary-of-run-time-configurations}@anchor{1b6}
@subsection Summary of Run-Time Configurations
@@ -22490,7 +22490,7 @@ ZCX
@node Specifying a Run-Time Library,GNU/Linux Topics,Run-Time Libraries,Platform-Specific Information
-@anchor{gnat_ugn/platform_specific_information specifying-a-run-time-library}@anchor{1b7}@anchor{gnat_ugn/platform_specific_information id4}@anchor{1b8}
+@anchor{gnat_ugn/platform_specific_information id4}@anchor{1b7}@anchor{gnat_ugn/platform_specific_information specifying-a-run-time-library}@anchor{1b8}
@section Specifying a Run-Time Library
@@ -22641,7 +22641,7 @@ Ignore : constant Boolean :=
@end example
@end quotation
-It gets the effective user id, and if it's not 0 (i.e. root), it raises
+It gets the effective user id, and if it’s not 0 (i.e. root), it raises
Program_Error.
@geindex Linux
@@ -22649,7 +22649,7 @@ Program_Error.
@geindex GNU/Linux
@node GNU/Linux Topics,Microsoft Windows Topics,Specifying a Run-Time Library,Platform-Specific Information
-@anchor{gnat_ugn/platform_specific_information id6}@anchor{1bb}@anchor{gnat_ugn/platform_specific_information gnu-linux-topics}@anchor{1bc}
+@anchor{gnat_ugn/platform_specific_information gnu-linux-topics}@anchor{1bb}@anchor{gnat_ugn/platform_specific_information id6}@anchor{1bc}
@section GNU/Linux Topics
@@ -22665,7 +22665,7 @@ This section describes topics that are specific to GNU/Linux platforms.
@subsection Required Packages on GNU/Linux
-GNAT requires the C library developer's package to be installed.
+GNAT requires the C library developer’s package to be installed.
The name of of that package depends on your GNU/Linux distribution:
@@ -22679,7 +22679,7 @@ Debian, Ubuntu: @code{libc6-dev} (normally installed by default).
@end itemize
If using the 32-bit version of GNAT on a 64-bit version of GNU/Linux,
-you'll need the 32-bit version of the following packages:
+you’ll need the 32-bit version of the following packages:
@itemize *
@@ -22697,7 +22697,7 @@ for those packages.
@geindex Windows
@node Microsoft Windows Topics,Mac OS Topics,GNU/Linux Topics,Platform-Specific Information
-@anchor{gnat_ugn/platform_specific_information microsoft-windows-topics}@anchor{1bf}@anchor{gnat_ugn/platform_specific_information id8}@anchor{1c0}
+@anchor{gnat_ugn/platform_specific_information id8}@anchor{1bf}@anchor{gnat_ugn/platform_specific_information microsoft-windows-topics}@anchor{1c0}
@section Microsoft Windows Topics
@@ -22718,7 +22718,7 @@ platforms.
@end menu
@node Using GNAT on Windows,Using a network installation of GNAT,,Microsoft Windows Topics
-@anchor{gnat_ugn/platform_specific_information using-gnat-on-windows}@anchor{1c1}@anchor{gnat_ugn/platform_specific_information id9}@anchor{1c2}
+@anchor{gnat_ugn/platform_specific_information id9}@anchor{1c1}@anchor{gnat_ugn/platform_specific_information using-gnat-on-windows}@anchor{1c2}
@subsection Using GNAT on Windows
@@ -22777,7 +22777,7 @@ import libraries. Interfacing must be done by the mean of DLLs.
@item
It is possible to link against Microsoft C libraries. Yet the preferred
solution is to use C/C++ compiler that comes with GNAT, since it
-doesn't require having two different development environments and makes the
+doesn’t require having two different development environments and makes the
inter-language debugging experience smoother.
@item
@@ -22822,7 +22822,7 @@ transfer of large amounts of data across the network and will likely cause
serious performance penalty.
@node CONSOLE and WINDOWS subsystems,Temporary Files,Using a network installation of GNAT,Microsoft Windows Topics
-@anchor{gnat_ugn/platform_specific_information id11}@anchor{1c5}@anchor{gnat_ugn/platform_specific_information console-and-windows-subsystems}@anchor{1c6}
+@anchor{gnat_ugn/platform_specific_information console-and-windows-subsystems}@anchor{1c5}@anchor{gnat_ugn/platform_specific_information id11}@anchor{1c6}
@subsection CONSOLE and WINDOWS subsystems
@@ -23087,7 +23087,7 @@ native SEH support is used.
@end menu
@node Windows Calling Conventions,Introduction to Dynamic Link Libraries DLLs,,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1cf}@anchor{gnat_ugn/platform_specific_information id14}@anchor{1d0}
+@anchor{gnat_ugn/platform_specific_information id14}@anchor{1cf}@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1d0}
@subsubsection Windows Calling Conventions
@@ -23100,9 +23100,9 @@ calling convention. All convention specifiers are ignored on this
platform.
When a subprogram @code{F} (caller) calls a subprogram @code{G}
-(callee), there are several ways to push @code{G}'s parameters on the
+(callee), there are several ways to push @code{G}’s parameters on the
stack and there are several possible scenarios to clean up the stack
-upon @code{G}'s return. A calling convention is an agreed upon software
+upon @code{G}’s return. A calling convention is an agreed upon software
protocol whereby the responsibilities between the caller (@code{F}) and
the callee (@code{G}) are clearly defined. Several calling conventions
are available for Windows:
@@ -23177,7 +23177,7 @@ DLL (in which case you should use the @code{Stdcall} calling
convention, @ref{1d3,,Stdcall Calling Convention}).
@node Stdcall Calling Convention,Win32 Calling Convention,C Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1d3}@anchor{gnat_ugn/platform_specific_information id16}@anchor{1d4}
+@anchor{gnat_ugn/platform_specific_information id16}@anchor{1d4}@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1d3}
@subsubsection @code{Stdcall} Calling Convention
@@ -23245,7 +23245,7 @@ then the imported routine is @code{retrieve_val}, that is, there is no
decoration at all. No leading underscore and no Stdcall suffix
@code{@@@emph{nn}}.
-This is especially important as in some special cases a DLL's entry
+This is especially important as in some special cases a DLL’s entry
point name lacks a trailing @code{@@@emph{nn}} while the exported
name generated for a call has it.
@@ -23274,7 +23274,7 @@ Note that to ease building cross-platform bindings this convention
will be handled as a @code{C} calling convention on non-Windows platforms.
@node Win32 Calling Convention,DLL Calling Convention,Stdcall Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1d5}@anchor{gnat_ugn/platform_specific_information id17}@anchor{1d6}
+@anchor{gnat_ugn/platform_specific_information id17}@anchor{1d5}@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1d6}
@subsubsection @code{Win32} Calling Convention
@@ -23282,7 +23282,7 @@ This convention, which is GNAT-specific is fully equivalent to the
@code{Stdcall} calling convention described above.
@node DLL Calling Convention,,Win32 Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information id18}@anchor{1d7}@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1d8}
+@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1d7}@anchor{gnat_ugn/platform_specific_information id18}@anchor{1d8}
@subsubsection @code{DLL} Calling Convention
@@ -23367,7 +23367,7 @@ application, a conflict will occur and the application will run
incorrectly. Hence, when possible, it is always preferable to use and
build relocatable DLLs. Both relocatable and non-relocatable DLLs are
supported by GNAT. Note that the @code{-s} linker option (see GNU Linker
-User's Guide) removes the debugging symbols from the DLL but the DLL can
+User’s Guide) removes the debugging symbols from the DLL but the DLL can
still be relocated.
As a side note, an interesting difference between Microsoft DLLs and
@@ -23396,7 +23396,7 @@ header files provided with the DLL.
The import library (@code{libAPI.dll.a} or @code{API.lib}). As previously
mentioned an import library is a statically linked library containing the
import table which will be filled at load time to point to the actual
-@code{API.dll} routines. Sometimes you don't have an import library for the
+@code{API.dll} routines. Sometimes you don’t have an import library for the
DLL you want to use. The following sections will explain how to build
one. Note that this is optional.
@@ -23468,7 +23468,7 @@ example a fictitious DLL called @code{API.dll}.
@end menu
@node Creating an Ada Spec for the DLL Services,Creating an Import Library,,Using DLLs with GNAT
-@anchor{gnat_ugn/platform_specific_information id21}@anchor{1dd}@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1de}
+@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1dd}@anchor{gnat_ugn/platform_specific_information id21}@anchor{1de}
@subsubsection Creating an Ada Spec for the DLL Services
@@ -23508,7 +23508,7 @@ end API;
@end quotation
@node Creating an Import Library,,Creating an Ada Spec for the DLL Services,Using DLLs with GNAT
-@anchor{gnat_ugn/platform_specific_information id22}@anchor{1df}@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1e0}
+@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1df}@anchor{gnat_ugn/platform_specific_information id22}@anchor{1e0}
@subsubsection Creating an Import Library
@@ -23570,7 +23570,7 @@ EXPORTS
@end table
Note that you must specify the correct suffix (@code{@@@emph{nn}})
-(see @ref{1cf,,Windows Calling Conventions}) for a Stdcall
+(see @ref{1d0,,Windows Calling Conventions}) for a Stdcall
calling convention function in the exported symbols list.
There can actually be other sections in a definition file, but these
@@ -23590,8 +23590,8 @@ $ dlltool API.dll -z API.def --export-all-symbols
@end example
Note that if some routines in the DLL have the @code{Stdcall} convention
-(@ref{1cf,,Windows Calling Conventions}) with stripped @code{@@@emph{nn}}
-suffix then you'll have to edit @code{api.def} to add it, and specify
+(@ref{1d0,,Windows Calling Conventions}) with stripped @code{@@@emph{nn}}
+suffix then you’ll have to edit @code{api.def} to add it, and specify
@code{-k} to @code{gnatdll} when creating the import library.
Here are some hints to find the right @code{@@@emph{nn}} suffix.
@@ -23648,7 +23648,7 @@ tools (@ref{1cc,,Mixed-Language Programming on Windows}).
To create a Microsoft-style import library for @code{API.dll} you
should create the .def file, then build the actual import library using
-Microsoft's @code{lib} utility:
+Microsoft’s @code{lib} utility:
@quotation
@@ -23668,7 +23668,7 @@ See the Microsoft documentation for further details about the usage of
@end quotation
@node Building DLLs with GNAT Project files,Building DLLs with GNAT,Using DLLs with GNAT,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id23}@anchor{1e5}@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1ce}
+@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1ce}@anchor{gnat_ugn/platform_specific_information id23}@anchor{1e5}
@subsubsection Building DLLs with GNAT Project files
@@ -23677,7 +23677,7 @@ See the Microsoft documentation for further details about the usage of
There is nothing specific to Windows in the build process.
See the @emph{Library Projects} section in the @emph{GNAT Project Manager}
-chapter of the @emph{GPRbuild User's Guide}.
+chapter of the @emph{GPRbuild User’s Guide}.
Due to a system limitation, it is not possible under Windows to create threads
when inside the @code{DllMain} routine which is used for auto-initialization
@@ -23724,7 +23724,7 @@ $ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ...
If you use a definition file you must export the elaboration procedures
for every package that required one. Elaboration procedures are named
-using the package name followed by "_E".
+using the package name followed by “_E”.
@item
Preparing DLL to be used.
@@ -23813,7 +23813,7 @@ binutils tool will not be relocatable anymore. To build a DLL without
debug information pass @code{-largs -s} to @code{gnatdll}. This
restriction does not apply to a DLL built using a Library Project.
See the @emph{Library Projects} section in the @emph{GNAT Project Manager}
-chapter of the @emph{GPRbuild User's Guide}.
+chapter of the @emph{GPRbuild User’s Guide}.
@c Limitations_When_Using_Ada_DLLs_from Ada:
@@ -23975,12 +23975,12 @@ directly from @code{DllMain} without having to provide an explicit
initialization routine. Unfortunately, it is not possible to call
@code{adainit} from the @code{DllMain} if your program has library level
tasks because access to the @code{DllMain} entry point is serialized by
-the system (that is, only a single thread can execute 'through' it at a
+the system (that is, only a single thread can execute ‘through’ it at a
time), which means that the GNAT run-time will deadlock waiting for the
newly created task to complete its initialization.
@node Ada DLLs and Finalization,Creating a Spec for Ada DLLs,Building DLLs with gnatdll,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id28}@anchor{1f1}@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{1ec}
+@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{1ec}@anchor{gnat_ugn/platform_specific_information id28}@anchor{1f1}
@subsubsection Ada DLLs and Finalization
@@ -23998,7 +23998,7 @@ during the DLL build process by the @code{gnatdll} tool
(@ref{1e3,,Using gnatdll}).
@node Creating a Spec for Ada DLLs,GNAT and Windows Resources,Ada DLLs and Finalization,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id29}@anchor{1f2}@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{1f3}
+@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{1f2}@anchor{gnat_ugn/platform_specific_information id29}@anchor{1f3}
@subsubsection Creating a Spec for Ada DLLs
@@ -24092,7 +24092,7 @@ EXPORTS
@end quotation
@node Using gnatdll,,Creating the Definition File,Creating a Spec for Ada DLLs
-@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1e3}@anchor{gnat_ugn/platform_specific_information id31}@anchor{1f5}
+@anchor{gnat_ugn/platform_specific_information id31}@anchor{1f5}@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1e3}
@subsubsection Using @code{gnatdll}
@@ -24196,7 +24196,7 @@ object files needed to build the DLL.
@item @code{-k}
-Removes the @code{@@@emph{nn}} suffix from the import library's exported
+Removes the @code{@@@emph{nn}} suffix from the import library’s exported
names, but keeps them for the link names. You must specify this
option if you want to use a @code{Stdcall} function in a DLL for which
the @code{@@@emph{nn}} suffix has been removed. This is the case for most
@@ -24401,7 +24401,7 @@ DLL in the static import library generated by @code{dlltool} with switch
@item @code{-k}
Kill @code{@@@emph{nn}} from exported names
-(@ref{1cf,,Windows Calling Conventions}
+(@ref{1d0,,Windows Calling Conventions}
for a discussion about @code{Stdcall}-style symbols.
@end table
@@ -24614,7 +24614,7 @@ $ windres -i myres.res -o myres.o
@end quotation
@node Using Resources,,Compiling Resources,GNAT and Windows Resources
-@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information id35}@anchor{1fe}
+@anchor{gnat_ugn/platform_specific_information id35}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{1fe}
@subsubsection Using Resources
@@ -24652,7 +24652,7 @@ cookbook-style sequence of steps to follow:
@item
First develop and build the GNAT shared library using a library project
-(let's assume the project is @code{mylib.gpr}, producing the library @code{libmylib.dll}):
+(let’s assume the project is @code{mylib.gpr}, producing the library @code{libmylib.dll}):
@end enumerate
@quotation
@@ -24695,7 +24695,7 @@ $ lib -machine:IX86 -def:libmylib.def -out:libmylib.lib
@end example
@end quotation
-If you are using a 64-bit toolchain, the above becomes...
+If you are using a 64-bit toolchain, the above becomes…
@quotation
@@ -24727,7 +24727,7 @@ or copy the DLL into into the directory containing the .exe.
@end enumerate
@node Debugging a DLL,Setting Stack Size from gnatlink,Using GNAT DLLs from Microsoft Visual Studio Applications,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id36}@anchor{201}@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{202}
+@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{201}@anchor{gnat_ugn/platform_specific_information id36}@anchor{202}
@subsubsection Debugging a DLL
@@ -24771,7 +24771,7 @@ tools suite used to build the DLL.
This is the simplest case. Both the DLL and the program have @code{GDB}
compatible debugging information. It is then possible to break anywhere in
-the process. Let's suppose here that the main procedure is named
+the process. Let’s suppose here that the main procedure is named
@code{ada_main} and that in the DLL there is an entry point named
@code{ada_dll}.
@@ -24815,7 +24815,7 @@ you can use the standard approach to debug the whole program
(@ref{14d,,Running and Debugging Ada Programs}).
@node Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Program and DLL Both Built with GCC/GNAT,Debugging a DLL
-@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{205}@anchor{gnat_ugn/platform_specific_information id38}@anchor{206}
+@anchor{gnat_ugn/platform_specific_information id38}@anchor{205}@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{206}
@subsubsection Program Built with Foreign Tools and DLL Built with GCC/GNAT
@@ -24926,7 +24926,7 @@ $ main
@end example
@item
-Use the Windows @emph{Task Manager} to find the process ID. Let's say
+Use the Windows @emph{Task Manager} to find the process ID. Let’s say
that the process PID for @code{main.exe} is 208.
@item
@@ -24971,7 +24971,7 @@ approach to debug a program as described in
@ref{14d,,Running and Debugging Ada Programs}.
@node Setting Stack Size from gnatlink,Setting Heap Size from gnatlink,Debugging a DLL,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{127}@anchor{gnat_ugn/platform_specific_information id39}@anchor{207}
+@anchor{gnat_ugn/platform_specific_information id39}@anchor{207}@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{127}
@subsubsection Setting Stack Size from @code{gnatlink}
@@ -25014,7 +25014,7 @@ because the comma is a separator for this option.
@end itemize
@node Setting Heap Size from gnatlink,,Setting Stack Size from gnatlink,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{128}@anchor{gnat_ugn/platform_specific_information id40}@anchor{208}
+@anchor{gnat_ugn/platform_specific_information id40}@anchor{208}@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{128}
@subsubsection Setting Heap Size from @code{gnatlink}
@@ -25047,7 +25047,7 @@ because the comma is a separator for this option.
@end itemize
@node Windows Specific Add-Ons,,Mixed-Language Programming on Windows,Microsoft Windows Topics
-@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{209}@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{20a}
+@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{209}@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{20a}
@subsection Windows Specific Add-Ons
@@ -25060,7 +25060,7 @@ This section describes the Windows specific add-ons.
@end menu
@node Win32Ada,wPOSIX,,Windows Specific Add-Ons
-@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{20b}@anchor{gnat_ugn/platform_specific_information id41}@anchor{20c}
+@anchor{gnat_ugn/platform_specific_information id41}@anchor{20b}@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{20c}
@subsubsection Win32Ada
@@ -25081,7 +25081,7 @@ end P;
@end quotation
To build the application you just need to call gprbuild for the
-application's project, here p.gpr:
+application’s project, here p.gpr:
@quotation
@@ -25114,7 +25114,7 @@ end P;
@end quotation
To build the application you just need to call gprbuild for the
-application's project, here p.gpr:
+application’s project, here p.gpr:
@quotation
@@ -25124,13 +25124,13 @@ gprbuild p.gpr
@end quotation
@node Mac OS Topics,,Microsoft Windows Topics,Platform-Specific Information
-@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{20f}@anchor{gnat_ugn/platform_specific_information id43}@anchor{210}
+@anchor{gnat_ugn/platform_specific_information id43}@anchor{20f}@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{210}
@section Mac OS Topics
@geindex OS X
-This section describes topics that are specific to Apple's OS X
+This section describes topics that are specific to Apple’s OS X
platform.
@menu
@@ -25166,7 +25166,7 @@ Start the Keychain Access application (in
@item
Select the Keychain Access -> Certificate Assistant ->
-Create a Certificate... menu
+Create a Certificate… menu
@item
Then:
@@ -25176,28 +25176,28 @@ Then:
@item
Choose a name for the new certificate (this procedure will use
-"gdb-cert" as an example)
+“gdb-cert” as an example)
@item
-Set "Identity Type" to "Self Signed Root"
+Set “Identity Type” to “Self Signed Root”
@item
-Set "Certificate Type" to "Code Signing"
+Set “Certificate Type” to “Code Signing”
@item
-Activate the "Let me override defaults" option
+Activate the “Let me override defaults” option
@end itemize
@item
-Click several times on "Continue" until the "Specify a Location
-For The Certificate" screen appears, then set "Keychain" to "System"
+Click several times on “Continue” until the “Specify a Location
+For The Certificate” screen appears, then set “Keychain” to “System”
@item
-Click on "Continue" until the certificate is created
+Click on “Continue” until the certificate is created
@item
Finally, in the view, double-click on the new certificate,
-and set "When using this certificate" to "Always Trust"
+and set “When using this certificate” to “Always Trust”
@item
Exit the Keychain Access application and restart the computer
@@ -25214,20 +25214,20 @@ $ codesign -f -s "gdb-cert" <gnat_install_prefix>/bin/gdb
@end example
@end quotation
-where "gdb-cert" should be replaced by the actual certificate
+where “gdb-cert” should be replaced by the actual certificate
name chosen above, and <gnat_install_prefix> should be replaced by
the location where you installed GNAT. Also, be sure that users are
in the Unix group @code{_developer}.
@node Example of Binder Output File,Elaboration Order Handling in GNAT,Platform-Specific Information,Top
-@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{e}@anchor{gnat_ugn/example_of_binder_output doc}@anchor{212}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{213}
+@anchor{gnat_ugn/example_of_binder_output doc}@anchor{212}@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{e}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{213}
@chapter Example of Binder Output File
@geindex Binder output (example)
This Appendix displays the source code for the output file
-generated by @emph{gnatbind} for a simple 'Hello World' program.
+generated by @emph{gnatbind} for a simple ‘Hello World’ program.
Comments have been added for clarification purposes.
@example
@@ -25972,7 +25972,7 @@ elaboration code in your own application).
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node Elaboration Order Handling in GNAT,Inline Assembler,Example of Binder Output File,Top
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{214}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{215}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{214}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{215}
@chapter Elaboration Order Handling in GNAT
@@ -26284,11 +26284,11 @@ body of Main
@end example
@end quotation
-The elaboration of @code{Server}'s spec materializes function @code{Func}, making it
-callable. The elaboration of @code{Client}'s spec elaborates the declaration of
+The elaboration of @code{Server}’s spec materializes function @code{Func}, making it
+callable. The elaboration of @code{Client}’s spec elaborates the declaration of
@code{Val}. This invokes function @code{Server.Func}, however the body of
-@code{Server.Func} has not been elaborated yet because @code{Server}'s body comes
-after @code{Client}'s spec in the elaboration order. As a result, the value of
+@code{Server.Func} has not been elaborated yet because @code{Server}’s body comes
+after @code{Client}’s spec in the elaboration order. As a result, the value of
constant @code{Val} is now undefined.
Without any guarantees from the language, an undetected ABE problem may hinder
@@ -26319,7 +26319,7 @@ however a compiler may not always find such an order due to complications with
respect to control and data flow.
@node Checking the Elaboration Order,Controlling the Elaboration Order in Ada,Elaboration Order,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{21a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{21b}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{21a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{21b}
@section Checking the Elaboration Order
@@ -26447,7 +26447,7 @@ but still strong enough to prevent ABE problems within a unit.
Pragma @code{Elaborate_Body} requires that the body of a unit is elaborated
immediately after its spec. This restriction guarantees that no client
scenario can invoke a server target before the target body has been
-elaborated because the spec and body are effectively "glued" together.
+elaborated because the spec and body are effectively “glued” together.
@example
package Server is
@@ -26708,7 +26708,7 @@ is that the program continues to stay in the last state (one or more correct
orders exist) even if maintenance changes the bodies of targets.
@node Controlling the Elaboration Order in GNAT,Mixing Elaboration Models,Controlling the Elaboration Order in Ada,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{21e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{21f}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{21e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{21f}
@section Controlling the Elaboration Order in GNAT
@@ -26838,7 +26838,7 @@ The dynamic, legacy, and static models can be relaxed using compiler switch
may not diagnose certain elaboration issues or install run-time checks.
@node Mixing Elaboration Models,ABE Diagnostics,Controlling the Elaboration Order in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{220}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{221}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{220}@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{221}
@section Mixing Elaboration Models
@@ -26918,7 +26918,7 @@ end Guaranteed_ABE;
@end example
@end quotation
-In the example above, the elaboration of @code{Guaranteed_ABE}'s body elaborates
+In the example above, the elaboration of @code{Guaranteed_ABE}’s body elaborates
the declaration of @code{Val}. This invokes function @code{ABE}, however the body of
@code{ABE} has not been elaborated yet. GNAT emits the following diagnostic:
@@ -26992,7 +26992,7 @@ declaration @code{Safe} because the body of function @code{ABE} has already been
elaborated at that point.
@node SPARK Diagnostics,Elaboration Circularities,ABE Diagnostics,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{224}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{225}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{224}@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{225}
@section SPARK Diagnostics
@@ -27018,7 +27018,7 @@ rules.
@end quotation
@node Elaboration Circularities,Resolving Elaboration Circularities,SPARK Diagnostics,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{226}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{227}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{226}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{227}
@section Elaboration Circularities
@@ -27389,7 +27389,7 @@ Use the relaxed dynamic-elaboration model, with compiler switches
@end itemize
@node Elaboration-related Compiler Switches,Summary of Procedures for Elaboration Control,Resolving Elaboration Circularities,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{22a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{22b}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{22a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{22b}
@section Elaboration-related Compiler Switches
@@ -27493,7 +27493,7 @@ eliminate some diagnostics and run-time checks.
@item @code{-gnatw.f}
-Turn on warnings for suspicious Subp'Access
+Turn on warnings for suspicious Subp’Access
When this switch is in effect, GNAT will treat @code{'Access} of an entry,
operator, or subprogram as a potential call to the target and issue warnings:
@@ -27771,7 +27771,7 @@ gdbstr (body)
@end quotation
@node Inline Assembler,GNU Free Documentation License,Elaboration Order Handling in GNAT,Top
-@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{10}@anchor{gnat_ugn/inline_assembler doc}@anchor{230}@anchor{gnat_ugn/inline_assembler id1}@anchor{231}
+@anchor{gnat_ugn/inline_assembler doc}@anchor{230}@anchor{gnat_ugn/inline_assembler id1}@anchor{231}@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{10}
@chapter Inline Assembler
@@ -27830,13 +27830,13 @@ and with assembly language programming.
@end menu
@node Basic Assembler Syntax,A Simple Example of Inline Assembler,,Inline Assembler
-@anchor{gnat_ugn/inline_assembler id2}@anchor{232}@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{233}
+@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{232}@anchor{gnat_ugn/inline_assembler id2}@anchor{233}
@section Basic Assembler Syntax
The assembler used by GNAT and gcc is based not on the Intel assembly
language, but rather on a language that descends from the AT&T Unix
-assembler @code{as} (and which is often referred to as 'AT&T syntax').
+assembler @code{as} (and which is often referred to as ‘AT&T syntax’).
The following table summarizes the main features of @code{as} syntax
and points out the differences from the Intel conventions.
See the gcc @code{as} and @code{gas} (an @code{as} macro
@@ -27846,7 +27846,7 @@ pre-processor) documentation for further information.
@display
@emph{Register names}@w{ }
@display
-gcc / @code{as}: Prefix with '%'; for example @code{%eax}@w{ }
+gcc / @code{as}: Prefix with ‘%’; for example @code{%eax}@w{ }
Intel: No extra punctuation; for example @code{eax}@w{ }
@end display
@end display
@@ -27857,7 +27857,7 @@ Intel: No extra punctuation; for example @code{eax}@w{ }
@display
@emph{Immediate operand}@w{ }
@display
-gcc / @code{as}: Prefix with '$'; for example @code{$4}@w{ }
+gcc / @code{as}: Prefix with ‘$’; for example @code{$4}@w{ }
Intel: No extra punctuation; for example @code{4}@w{ }
@end display
@end display
@@ -27868,7 +27868,7 @@ Intel: No extra punctuation; for example @code{4}@w{ }
@display
@emph{Address}@w{ }
@display
-gcc / @code{as}: Prefix with '$'; for example @code{$loc}@w{ }
+gcc / @code{as}: Prefix with ‘$’; for example @code{$loc}@w{ }
Intel: No extra punctuation; for example @code{loc}@w{ }
@end display
@end display
@@ -27901,8 +27901,8 @@ Intel: Square brackets; for example @code{[eax]}@w{ }
@display
@emph{Hexadecimal numbers}@w{ }
@display
-gcc / @code{as}: Leading '0x' (C language syntax); for example @code{0xA0}@w{ }
-Intel: Trailing 'h'; for example @code{A0h}@w{ }
+gcc / @code{as}: Leading ‘0x’ (C language syntax); for example @code{0xA0}@w{ }
+Intel: Trailing ‘h’; for example @code{A0h}@w{ }
@end display
@end display
@@ -28069,9 +28069,9 @@ L1:
The assembly code you included is clearly indicated by
the compiler, between the @code{#APP} and @code{#NO_APP}
-delimiters. The character before the 'APP' and 'NOAPP'
-can differ on different targets. For example, GNU/Linux uses '#APP' while
-on NT you will see '/APP'.
+delimiters. The character before the ‘APP’ and ‘NOAPP’
+can differ on different targets. For example, GNU/Linux uses ‘#APP’ while
+on NT you will see ‘/APP’.
If you make a mistake in your assembler code (such as using the
wrong size modifier, or using a wrong operand for the instruction) GNAT
@@ -28235,7 +28235,7 @@ Unsigned_32'Asm_Output ("=r", Flags);
uses the @code{"r"} (register) constraint, telling the compiler to
store the variable in a register.
-If the constraint is preceded by the equal character '=', it tells
+If the constraint is preceded by the equal character ‘=’, it tells
the compiler that the variable will be used to store data into it.
In the @code{Get_Flags} example, we used the @code{"g"} (global) constraint,
@@ -28558,7 +28558,7 @@ _increment__incr.1:
For a short subprogram such as the @code{Incr} function in the previous
section, the overhead of the call and return (creating / deleting the stack
frame) can be significant, compared to the amount of code in the subprogram
-body. A solution is to apply Ada's @code{Inline} pragma to the subprogram,
+body. A solution is to apply Ada’s @code{Inline} pragma to the subprogram,
which directs the compiler to expand invocations of the subprogram at the
point(s) of call, instead of setting up a stack frame for out-of-line calls.
Here is the resulting program:
@@ -28622,7 +28622,7 @@ movl %esi,%eax
thus saving the overhead of stack frame setup and an out-of-line call.
@node Other Asm Functionality,,Inlining Inline Assembler Code,Inline Assembler
-@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{23c}@anchor{gnat_ugn/inline_assembler id7}@anchor{23d}
+@anchor{gnat_ugn/inline_assembler id7}@anchor{23c}@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{23d}
@section Other @code{Asm} Functionality
@@ -28637,7 +28637,7 @@ and @code{Volatile}, which inhibits unwanted optimizations.
@end menu
@node The Clobber Parameter,The Volatile Parameter,,Other Asm Functionality
-@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{23e}@anchor{gnat_ugn/inline_assembler id8}@anchor{23f}
+@anchor{gnat_ugn/inline_assembler id8}@anchor{23e}@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{23f}
@subsection The @code{Clobber} Parameter
@@ -28650,7 +28650,7 @@ the eax register). But more generally, the compiler needs an explicit
identification of the registers that are used by the Inline Assembly
statements.
-Using a register that the compiler doesn't know about
+Using a register that the compiler doesn’t know about
could be a side effect of an instruction (like @code{mull}
storing its result in both eax and edx).
It can also arise from explicit register usage in your
@@ -28694,14 +28694,14 @@ The @code{Clobber} parameter has several additional uses:
@itemize *
@item
-Use 'register' name @code{cc} to indicate that flags might have changed
+Use ‘register’ name @code{cc} to indicate that flags might have changed
@item
-Use 'register' name @code{memory} if you changed a memory location
+Use ‘register’ name @code{memory} if you changed a memory location
@end itemize
@node The Volatile Parameter,,The Clobber Parameter,Other Asm Functionality
-@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{240}@anchor{gnat_ugn/inline_assembler id9}@anchor{241}
+@anchor{gnat_ugn/inline_assembler id9}@anchor{240}@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{241}
@subsection The @code{Volatile} Parameter
@@ -28733,11 +28733,11 @@ By default, @code{Volatile} is set to @code{False} unless there is no
Although setting @code{Volatile} to @code{True} prevents unwanted
optimizations, it will also disable other optimizations that might be
important for efficiency. In general, you should set @code{Volatile}
-to @code{True} only if the compiler's optimizations have created
+to @code{True} only if the compiler’s optimizations have created
problems.
@node GNU Free Documentation License,Index,Inline Assembler,Top
-@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{242}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{243}
+@anchor{share/gnu_free_documentation_license doc}@anchor{242}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{243}
@chapter GNU Free Documentation License
@@ -28752,14 +28752,14 @@ license document, but changing it is not allowed.
@strong{Preamble}
The purpose of this License is to make a manual, textbook, or other
-functional and useful document "free" in the sense of freedom: to
+functional and useful document “free” in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
-This License is a kind of "copyleft", which means that derivative
+This License is a kind of “copyleft”, which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
@@ -28780,17 +28780,17 @@ distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The @strong{Document}, below,
refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "@strong{you}". You accept the license if you
+licensee, and is addressed as “@strong{you}”. You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
-A "@strong{Modified Version}" of the Document means any work containing the
+A “@strong{Modified Version}” of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
-A "@strong{Secondary Section}" is a named appendix or a front-matter section of
+A “@strong{Secondary Section}” is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
+publishers or authors of the Document to the Document’s overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (Thus, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
@@ -28799,7 +28799,7 @@ connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
-The "@strong{Invariant Sections}" are certain Secondary Sections whose titles
+The “@strong{Invariant Sections}” are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
@@ -28807,12 +28807,12 @@ allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
-The "@strong{Cover Texts}" are certain short passages of text that are listed,
+The “@strong{Cover Texts}” are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
-A "@strong{Transparent}" copy of the Document means a machine-readable copy,
+A “@strong{Transparent}” copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
@@ -28823,7 +28823,7 @@ to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
-of text. A copy that is not "Transparent" is called @strong{Opaque}.
+of text. A copy that is not “Transparent” is called @strong{Opaque}.
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
@@ -28836,24 +28836,24 @@ processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
-The "@strong{Title Page}" means, for a printed book, the title page itself,
+The “@strong{Title Page}” means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
+formats which do not have any title page as such, “Title Page” means
+the text near the most prominent appearance of the work’s title,
preceding the beginning of the body of the text.
-The "@strong{publisher}" means any person or entity that distributes
+The “@strong{publisher}” means any person or entity that distributes
copies of the Document to the public.
-A section "@strong{Entitled XYZ}" means a named subunit of the Document whose
+A section “@strong{Entitled XYZ}” means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as "@strong{Acknowledgements}",
-"@strong{Dedications}", "@strong{Endorsements}", or "@strong{History}".)
-To "@strong{Preserve the Title}"
+specific section name mentioned below, such as “@strong{Acknowledgements}”,
+“@strong{Dedications}”, “@strong{Endorsements}”, or “@strong{History}”.)
+To “@strong{Preserve the Title}”
of such a section when you modify the Document means that it remains a
-section "Entitled XYZ" according to this definition.
+section “Entitled XYZ” according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
@@ -28881,7 +28881,7 @@ you may publicly display copies.
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
+Document’s license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
@@ -28958,16 +28958,16 @@ terms of this License, in the form shown in the Addendum below.
@item
Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
+and required Cover Texts given in the Document’s license notice.
@item
Include an unaltered copy of this License.
@item
-Preserve the section Entitled "History", Preserve its Title, and add
+Preserve the section Entitled “History”, Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
-there is no section Entitled "History" in the Document, create one
+there is no section Entitled “History” in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
@@ -28976,13 +28976,13 @@ Version as stated in the previous sentence.
Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
-it was based on. These may be placed in the "History" section.
+it was based on. These may be placed in the “History” section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
@item
-For any section Entitled "Acknowledgements" or "Dedications",
+For any section Entitled “Acknowledgements” or “Dedications”,
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
@@ -28993,11 +28993,11 @@ unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
@item
-Delete any section Entitled "Endorsements". Such a section
+Delete any section Entitled “Endorsements”. Such a section
may not be included in the Modified Version.
@item
-Do not retitle any existing section to be Entitled "Endorsements"
+Do not retitle any existing section to be Entitled “Endorsements”
or to conflict in title with any Invariant Section.
@item
@@ -29008,12 +29008,12 @@ If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
+list of Invariant Sections in the Modified Version’s license notice.
These titles must be distinct from any other section titles.
-You may add a section Entitled "Endorsements", provided it contains
+You may add a section Entitled “Endorsements”, provided it contains
nothing but endorsements of your Modified Version by various
-parties---for example, statements of peer review or that the text has
+parties—for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
@@ -29049,11 +29049,11 @@ author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
-In the combination, you must combine any sections Entitled "History"
+In the combination, you must combine any sections Entitled “History”
in the various original documents, forming one section Entitled
-"History"; likewise combine any sections Entitled "Acknowledgements",
-and any sections Entitled "Dedications". You must delete all sections
-Entitled "Endorsements".
+“History”; likewise combine any sections Entitled “Acknowledgements”,
+and any sections Entitled “Dedications”. You must delete all sections
+Entitled “Endorsements”.
@strong{6. COLLECTIONS OF DOCUMENTS}
@@ -29072,16 +29072,16 @@ other respects regarding verbatim copying of that document.
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an "aggregate" if the copyright
+distribution medium, is called an “aggregate” if the copyright
resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
+of the compilation’s users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
+the entire aggregate, the Document’s Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
@@ -29102,8 +29102,8 @@ of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve
+If a section in the Document is Entitled “Acknowledgements”,
+“Dedications”, or “History”, the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
@@ -29144,37 +29144,37 @@ differ in detail to address new problems or concerns. See
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
+License “or any later version” applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
-License can be used, that proxy's public statement of acceptance of a
+License can be used, that proxy’s public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.
@strong{11. RELICENSING}
-"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
-"Massive Multiauthor Collaboration" (or "MMC") contained in the
+“Massive Multiauthor Collaboration” (or “MMC”) contained in the
site means any set of copyrightable works thus published on the MMC
site.
-"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
-"Incorporate" means to publish or republish a Document, in whole or
+“Incorporate” means to publish or republish a Document, in whole or
in part, as part of another Document.
-An MMC is "eligible for relicensing" if it is licensed under this
+An MMC is “eligible for relicensing” if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole
or in part into the MMC, (1) had no cover texts or invariant sections,
@@ -29197,12 +29197,12 @@ Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-A copy of the license is included in the section entitled "GNU
-Free Documentation License".
+A copy of the license is included in the section entitled “GNU
+Free Documentation License”.
@end quotation
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the "with ... Texts." line with this:
+replace the “with … Texts.” line with this:
@quotation
@@ -29225,8 +29225,8 @@ to permit their use in free software.
@printindex ge
-@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
@anchor{cf}@w{ }
+@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
@c %**end of body
@bye
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index eb6e6d9..a987594 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -215,6 +215,7 @@
#if !(defined (VMS) || defined (__MINGW32__))
#include <sys/socket.h>
#include <sys/un.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 7e4a4d9..b99f3fd 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -635,12 +635,6 @@ package body Impunit is
("a-sttebu", T), -- Ada.Strings.Text_Buffers
("a-stbuun", T), -- Ada.Strings.Text_Buffers.Unbounded
("a-stbubo", T), -- Ada.Strings.Text_Buffers.Bounded
- ("a-stteou", T), -- Ada.Strings.Text_Output
- ("a-stouut", T), -- Ada.Strings.Text_Output.Utils
- ("a-stoufi", T), -- Ada.Strings.Text_Output.Files
- ("a-stobfi", T), -- Ada.Strings.Text_Output.Basic_Files
- ("a-stobbu", T), -- Ada.Strings.Text_Output.Bit_Buckets
- ("a-stoufo", T), -- Ada.Strings.Text_Output.Formatting
("a-strsto", T), -- Ada.Streams.Storage
("a-ststbo", T), -- Ada.Streams.Storage.Bounded
("a-ststun", T), -- Ada.Streams.Storage.Unbounded
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index fc704e6..6c330b2 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -3008,10 +3008,7 @@ package body Inline is
if Nkind (A) = N_Type_Conversion
and then Ekind (F) /= E_In_Parameter
then
- New_A :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Etype (F), Loc),
- Expression => Relocate_Node (Expression (A)));
+ New_A := Unchecked_Convert_To (Etype (F), Expression (A));
-- In GNATprove mode, keep the most precise type of the actual for
-- the temporary variable, when the formal type is unconstrained.
@@ -4809,7 +4806,7 @@ package body Inline is
end if;
end Instantiate_Body;
- J, K : Nat;
+ J, K : Nat;
Info : Pending_Body_Info;
-- Start of processing for Instantiate_Bodies
@@ -5156,17 +5153,12 @@ package body Inline is
--------------------------
procedure Remove_Dead_Instance (N : Node_Id) is
- J : Int;
-
begin
- J := 0;
- while J <= Pending_Instantiations.Last loop
+ for J in 0 .. Pending_Instantiations.Last loop
if Pending_Instantiations.Table (J).Inst_Node = N then
Pending_Instantiations.Table (J).Inst_Node := Empty;
return;
end if;
-
- J := J + 1;
end loop;
end Remove_Dead_Instance;
diff --git a/gcc/ada/krunch.adb b/gcc/ada/krunch.adb
index 4cff3ca..f698d88 100644
--- a/gcc/ada/krunch.adb
+++ b/gcc/ada/krunch.adb
@@ -92,15 +92,16 @@ begin
Startloc := 3;
Buffer (2 .. Len - 5) := Buffer (7 .. Len);
Curlen := Len - 5;
- if Buffer (Curlen - 2 .. Curlen) = "128"
- or else Buffer (3 .. 9) = "exn_lll"
- or else Buffer (3 .. 9) = "exp_lll"
- or else Buffer (3 .. 9) = "img_lll"
- or else Buffer (3 .. 9) = "val_lll"
- or else Buffer (3 .. 9) = "wid_lll"
- or else (Buffer (3 .. 6) = "pack" and then Curlen = 10)
+ if (Curlen >= 3 and then Buffer (Curlen - 2 .. Curlen) = "128")
+ or else (Len >= 9 and then
+ (Buffer (3 .. 9) = "exn_lll"
+ or else Buffer (3 .. 9) = "exp_lll"
+ or else Buffer (3 .. 9) = "img_lll"
+ or else Buffer (3 .. 9) = "val_lll"
+ or else Buffer (3 .. 9) = "wid_lll"))
+ or else (Curlen = 10 and then Buffer (3 .. 6) = "pack")
then
- if Buffer (3 .. 15) = "compare_array" then
+ if Len >= 15 and then Buffer (3 .. 15) = "compare_array" then
Buffer (3 .. 4) := "ca";
Buffer (5 .. Curlen - 11) := Buffer (16 .. Curlen);
Curlen := Curlen - 11;
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb
index 5bafbcc..f716488 100644
--- a/gcc/ada/layout.adb
+++ b/gcc/ada/layout.adb
@@ -77,7 +77,7 @@ package body Layout is
begin
-- Nothing to do if size unknown
- if Unknown_Esize (E) then
+ if not Known_Esize (E) then
return;
end if;
@@ -119,7 +119,7 @@ package body Layout is
-- Now we have the size set, it must be a multiple of the alignment
-- nothing more we can do here if the alignment is unknown here.
- if Unknown_Alignment (E) then
+ if not Known_Alignment (E) then
return;
end if;
@@ -270,15 +270,15 @@ package body Layout is
Desig_Type := Non_Limited_View (Designated_Type (E));
end if;
- -- If Esize already set (e.g. by a size clause), then nothing further
- -- to be done here.
+ -- If Esize already set (e.g. by a size or value size clause), then
+ -- nothing further to be done here.
if Known_Esize (E) then
null;
- -- Access to subprogram is a strange beast, and we let the backend
- -- figure out what is needed (it may be some kind of fat pointer,
- -- including the static link for example.
+ -- Access to protected subprogram is a strange beast, and we let the
+ -- backend figure out what is needed (it may be some kind of fat
+ -- pointer, including the static link for example).
elsif Is_Access_Protected_Subprogram_Type (E) then
null;
@@ -404,7 +404,7 @@ package body Layout is
-- it now to a copy of the Esize if the Esize is set.
else
- if Known_Esize (E) and then Unknown_RM_Size (E) then
+ if Known_Esize (E) and then not Known_RM_Size (E) then
Set_RM_Size (E, Esize (E));
end if;
end if;
@@ -425,15 +425,15 @@ package body Layout is
PAT : constant Entity_Id := Packed_Array_Impl_Type (E);
begin
- if Unknown_Esize (E) then
+ if not Known_Esize (E) then
Set_Esize (E, Esize (PAT));
end if;
- if Unknown_RM_Size (E) then
+ if not Known_RM_Size (E) then
Set_RM_Size (E, RM_Size (PAT));
end if;
- if Unknown_Alignment (E) then
+ if not Known_Alignment (E) then
Set_Alignment (E, Alignment (PAT));
end if;
end;
@@ -446,7 +446,7 @@ package body Layout is
-- gave up because, in this case, the object size is not a multiple
-- of the alignment and, therefore, cannot be the component size.
- if Ekind (E) = E_Array_Type and then Unknown_Component_Size (E) then
+ if Ekind (E) = E_Array_Type and then not Known_Component_Size (E) then
declare
CT : constant Entity_Id := Component_Type (E);
@@ -478,7 +478,7 @@ package body Layout is
if Is_Array_Type (E)
and then not Is_Packed (E)
- and then Unknown_Alignment (E)
+ and then not Known_Alignment (E)
and then Known_Alignment (Component_Type (E))
and then Known_Static_Component_Size (E)
and then Known_Static_Esize (Component_Type (E))
@@ -487,6 +487,59 @@ package body Layout is
then
Set_Alignment (E, Alignment (Component_Type (E)));
end if;
+
+ -- If packing was requested, the one-dimensional array is constrained
+ -- with static bounds, the component size was set explicitly, and
+ -- the alignment is known, we can set (if not set explicitly) the
+ -- RM_Size and the Esize of the array type, as RM_Size is equal to
+ -- (arr'length * arr'component_size) and Esize is the same value
+ -- rounded to the next multiple of arr'alignment. This is not
+ -- applicable to packed arrays that are implemented specially
+ -- in GNAT, i.e. when Packed_Array_Impl_Type is set.
+
+ if Is_Array_Type (E)
+ and then Present (First_Index (E)) -- Skip types in error
+ and then Number_Dimensions (E) = 1
+ and then not Present (Packed_Array_Impl_Type (E))
+ and then Has_Pragma_Pack (E)
+ and then Is_Constrained (E)
+ and then Compile_Time_Known_Bounds (E)
+ and then Known_Component_Size (E)
+ and then Known_Alignment (E)
+ then
+ declare
+ Abits : constant Int := UI_To_Int (Alignment (E)) * SSU;
+ Lo, Hi : Node_Id;
+ Siz : Uint;
+
+ begin
+ Get_Index_Bounds (First_Index (E), Lo, Hi);
+
+ -- Even if the bounds are known at compile time, they could
+ -- have been replaced by an error node. Check each bound
+ -- explicitly.
+
+ if Compile_Time_Known_Value (Lo)
+ and then Compile_Time_Known_Value (Hi)
+ then
+ Siz := (Expr_Value (Hi) - Expr_Value (Lo) + 1)
+ * Component_Size (E);
+
+ -- Do not overwrite a different value of 'Size specified
+ -- explicitly by the user. In that case, also do not set
+ -- Esize.
+
+ if not Known_RM_Size (E) or else RM_Size (E) = Siz then
+ Set_RM_Size (E, Siz);
+
+ if not Known_Esize (E) then
+ Siz := ((Siz + (Abits - 1)) / Abits) * Abits;
+ Set_Esize (E, Siz);
+ end if;
+ end if;
+ end if;
+ end;
+ end if;
end if;
-- Even if the backend performs the layout, we still do a little in
@@ -523,7 +576,7 @@ package body Layout is
-- arrays when passed to subprogram parameters (see special test
-- in Exp_Ch6.Expand_Actuals).
- if not Is_Packed (E) and then Unknown_Alignment (E) then
+ if not Is_Packed (E) and then not Known_Alignment (E) then
if Known_Static_Component_Size (E)
and then Component_Size (E) = 1
then
@@ -695,7 +748,7 @@ package body Layout is
if Known_Static_Esize (E) then
Siz := Esize (E);
- elsif Unknown_Esize (E) and then Known_Static_RM_Size (E) then
+ elsif not Known_Esize (E) and then Known_Static_RM_Size (E) then
Siz := RM_Size (E);
else
return;
@@ -800,7 +853,7 @@ package body Layout is
if Calign > Align
and then
- (Unknown_Esize (Comp)
+ (not Known_Esize (Comp)
or else (Known_Static_Esize (Comp)
and then
Esize (Comp) = Calign * SSU))
@@ -967,7 +1020,7 @@ package body Layout is
-- If alignment is currently not set, then we can safely set it to
-- this new calculated value.
- if Unknown_Alignment (E) then
+ if not Known_Alignment (E) then
Init_Alignment (E, A);
-- Cases where we have inherited an alignment
diff --git a/gcc/ada/layout.ads b/gcc/ada/layout.ads
index 32caee0..89ee5bd 100644
--- a/gcc/ada/layout.ads
+++ b/gcc/ada/layout.ads
@@ -32,10 +32,9 @@ with Types; use Types;
package Layout is
- -- The following procedures are called from Freeze, so all entities
- -- for types and objects that get frozen (which should be all such
- -- entities which are seen by the back end) will get laid out by one
- -- of these two procedures.
+ -- The following procedures are called from Freeze, so all entities for
+ -- types and objects that get frozen (i.e. all types and objects seen by
+ -- the back end) will get laid out by one of these two procedures.
procedure Layout_Type (E : Entity_Id);
-- This procedure may set or adjust the fields Esize, RM_Size and
diff --git a/gcc/ada/lib-load.adb b/gcc/ada/lib-load.adb
index 330faa7..737762c 100644
--- a/gcc/ada/lib-load.adb
+++ b/gcc/ada/lib-load.adb
@@ -364,7 +364,7 @@ package body Lib.Load is
Error_Location => No_Location,
Expected_Unit => No_Unit_Name,
Fatal_Error => None,
- Generate_Code => False,
+ Generate_Code => True,
Has_RACW => False,
Filler => False,
Ident_String => Empty,
@@ -396,14 +396,14 @@ package body Lib.Load is
---------------
function Load_Unit
- (Load_Name : Unit_Name_Type;
- Required : Boolean;
- Error_Node : Node_Id;
- Subunit : Boolean;
- Corr_Body : Unit_Number_Type := No_Unit;
- Renamings : Boolean := False;
- With_Node : Node_Id := Empty;
- PMES : Boolean := False) return Unit_Number_Type
+ (Load_Name : Unit_Name_Type;
+ Required : Boolean;
+ Error_Node : Node_Id;
+ Subunit : Boolean;
+ Corr_Body : Unit_Number_Type := No_Unit;
+ Renamings : Boolean := False;
+ With_Node : Node_Id := Empty;
+ PMES : Boolean := False) return Unit_Number_Type
is
Calling_Unit : Unit_Number_Type;
Uname_Actual : Unit_Name_Type;
@@ -451,8 +451,8 @@ package body Lib.Load is
With_Node => With_Node);
if Unump = No_Unit then
- Parsing_Main_Extended_Source := Save_PMES;
- return No_Unit;
+ Unum := No_Unit;
+ goto Done;
end if;
-- If parent is a renaming, then we use the renamed package as
@@ -823,7 +823,7 @@ package body Lib.Load is
Units.Table (Calling_Unit).Fatal_Error := Error_Detected;
-- If with'ed unit had an ignored error, then propagate it
- -- but do not overide an existring setting.
+ -- but do not overide an existing setting.
when Error_Ignored =>
if Units.Table (Calling_Unit).Fatal_Error = None then
@@ -900,7 +900,7 @@ package body Lib.Load is
Remove_Unit (Unum);
-- If unit not required, remove load stack entry and the junk
- -- file table entry, and return No_Unit to indicate not found,
+ -- file table entry, and return No_Unit to indicate not found.
else
Load_Stack.Decrement_Last;
@@ -964,13 +964,12 @@ package body Lib.Load is
Units.Increment_Last;
if In_Main then
- Units.Table (Units.Last) := Units.Table (Main_Unit);
- Units.Table (Units.Last).Cunit := Library_Unit (N);
- Units.Table (Units.Last).Generate_Code := True;
+ Units.Table (Units.Last) := Units.Table (Main_Unit);
+ Units.Table (Units.Last).Cunit := Library_Unit (N);
Init_Unit_Name (Units.Last, Unit_Name (Main_Unit));
- Units.Table (Main_Unit).Cunit := N;
- Units.Table (Main_Unit).Version := Source_Checksum (Sind);
+ Units.Table (Main_Unit).Cunit := N;
+ Units.Table (Main_Unit).Version := Source_Checksum (Sind);
Init_Unit_Name (Main_Unit,
Get_Body_Name
(Unit_Name (Get_Cunit_Unit_Number (Library_Unit (N)))));
diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb
index 4dfb68e..738a91e 100644
--- a/gcc/ada/lib-writ.adb
+++ b/gcc/ada/lib-writ.adb
@@ -137,7 +137,8 @@ package body Lib.Writ is
------------------------------
procedure Ensure_System_Dependency is
- System_Uname : Unit_Name_Type;
+ System_Uname : constant Unit_Name_Type :=
+ Name_To_Unit_Name (Name_System);
-- Unit name for system spec if needed for dummy entry
System_Fname : File_Name_Type;
@@ -146,11 +147,9 @@ package body Lib.Writ is
begin
-- Nothing to do if we already compiled System
- for Unum in Units.First .. Last_Unit loop
- if Source_Index (Unum) = System_Source_File_Index then
- return;
- end if;
- end loop;
+ if Is_Loaded (System_Uname) then
+ return;
+ end if;
-- If no entry for system.ads in the units table, then add a entry
-- to the units table for system.ads, which will be referenced when
@@ -158,9 +157,6 @@ package body Lib.Writ is
-- on system as a result of Targparm scanning the system.ads file to
-- determine the target dependent parameters for the compilation.
- Name_Len := 6;
- Name_Buffer (1 .. 6) := "system";
- System_Uname := Name_To_Unit_Name (Name_Enter);
System_Fname := File_Name (System_Source_File_Index);
Units.Increment_Last;
@@ -709,7 +705,7 @@ package body Lib.Writ is
Write_Info_Char (' ');
case Pragma_Name (N) is
- when Name_Annotate =>
+ when Name_Annotate | Name_GNAT_Annotate =>
C := 'A';
when Name_Comment =>
C := 'C';
@@ -1255,9 +1251,10 @@ package body Lib.Writ is
-- for which we have generated code
for Unit in Units.First .. Last_Unit loop
- if Units.Table (Unit).Generate_Code or else Unit = Main_Unit then
+ if Units.Table (Unit).Generate_Code then
if not Has_No_Elaboration_Code (Cunit (Unit)) then
Main_Restrictions.Violated (No_Elaboration_Code) := True;
+ exit;
end if;
end if;
end loop;
diff --git a/gcc/ada/lib-writ.ads b/gcc/ada/lib-writ.ads
index b8370fa..ce5398b 100644
--- a/gcc/ada/lib-writ.ads
+++ b/gcc/ada/lib-writ.ads
@@ -1053,6 +1053,9 @@ package Lib.Writ is
-- The Object parameter is true if an object file is created, and false
-- otherwise. Note that the pseudo-object file generated in GNATprove mode
-- does count as an object file from this point of view.
+ -- May output duplicate D lines caused by generic instantiations. This is
+ -- by design as GNATcoverage relies on them for its coverage of generic
+ -- instantiations, although this may be revisited in the future.
procedure Add_Preprocessing_Dependency (S : Source_File_Index);
-- Indicate that there is a dependency to be added on a preprocessing data
diff --git a/gcc/ada/lib.adb b/gcc/ada/lib.adb
index 31a6b8c..44a4af0 100644
--- a/gcc/ada/lib.adb
+++ b/gcc/ada/lib.adb
@@ -128,12 +128,12 @@ package body Lib is
return Units.Table (U).Is_Predefined_Renaming;
end Is_Predefined_Renaming;
- function Is_Internal_Unit (U : Unit_Number_Type) return Boolean is
+ function Is_Internal_Unit (U : Unit_Number_Type) return Boolean is
begin
return Units.Table (U).Is_Internal_Unit;
end Is_Internal_Unit;
- function Is_Predefined_Unit (U : Unit_Number_Type) return Boolean is
+ function Is_Predefined_Unit (U : Unit_Number_Type) return Boolean is
begin
return Units.Table (U).Is_Predefined_Unit;
end Is_Predefined_Unit;
@@ -482,18 +482,12 @@ package body Lib is
-- body of the same unit. The location in the spec is considered
-- earlier.
- if Nkind (Unit1) = N_Subprogram_Body
- or else
- Nkind (Unit1) = N_Package_Body
- then
+ if Nkind (Unit1) in N_Subprogram_Body | N_Package_Body then
if Library_Unit (Cunit (Unum1)) = Cunit (Unum2) then
return Yes_After;
end if;
- elsif Nkind (Unit2) = N_Subprogram_Body
- or else
- Nkind (Unit2) = N_Package_Body
- then
+ elsif Nkind (Unit2) in N_Subprogram_Body | N_Package_Body then
if Library_Unit (Cunit (Unum2)) = Cunit (Unum1) then
return Yes_Before;
end if;
@@ -1180,10 +1174,9 @@ package body Lib is
procedure Remove_Unit (U : Unit_Number_Type) is
begin
- if U = Units.Last then
- Unit_Names.Set (Unit_Name (U), No_Unit);
- Units.Decrement_Last;
- end if;
+ pragma Assert (U = Units.Last);
+ Unit_Names.Set (Unit_Name (U), No_Unit);
+ Units.Decrement_Last;
end Remove_Unit;
----------------------------------
diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads
index 1450124..f2c6ef3 100644
--- a/gcc/ada/lib.ads
+++ b/gcc/ada/lib.ads
@@ -926,7 +926,9 @@ private
-- The following table records a mapping between a name and the entry in
-- the units table whose Unit_Name is this name. It is used to speed up
-- the Is_Loaded function, whose original implementation (linear search)
- -- could account for 2% of the time spent in the front end. Note that, in
+ -- could account for 2% of the time spent in the front end. When the unit
+ -- is an instance of a generic, the unit might get duplicated in the unit
+ -- table - see Make_Instance_Unit for more information. Note that, in
-- the case of source files containing multiple units, the units table may
-- temporarily contain two entries with the same Unit_Name during parsing,
-- which means that the mapping must be to the first entry in the table.
diff --git a/gcc/ada/libgnarl/s-linux.ads b/gcc/ada/libgnarl/s-linux.ads
index 16a28ac..2251f2d 100644
--- a/gcc/ada/libgnarl/s-linux.ads
+++ b/gcc/ada/libgnarl/s-linux.ads
@@ -36,6 +36,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__alpha.ads b/gcc/ada/libgnarl/s-linux__alpha.ads
index cd9a62e..06b12f2 100644
--- a/gcc/ada/libgnarl/s-linux__alpha.ads
+++ b/gcc/ada/libgnarl/s-linux__alpha.ads
@@ -36,6 +36,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__android.ads b/gcc/ada/libgnarl/s-linux__android.ads
index 5b23b73..d2b689e 100644
--- a/gcc/ada/libgnarl/s-linux__android.ads
+++ b/gcc/ada/libgnarl/s-linux__android.ads
@@ -36,6 +36,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__hppa.ads b/gcc/ada/libgnarl/s-linux__hppa.ads
index 73815d2..03869df 100644
--- a/gcc/ada/libgnarl/s-linux__hppa.ads
+++ b/gcc/ada/libgnarl/s-linux__hppa.ads
@@ -36,6 +36,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__mips.ads b/gcc/ada/libgnarl/s-linux__mips.ads
index f63640c..3660ee9 100644
--- a/gcc/ada/libgnarl/s-linux__mips.ads
+++ b/gcc/ada/libgnarl/s-linux__mips.ads
@@ -35,6 +35,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype int is Interfaces.C.int;
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__riscv.ads b/gcc/ada/libgnarl/s-linux__riscv.ads
index d8d0f63..e3f7cc3 100644
--- a/gcc/ada/libgnarl/s-linux__riscv.ads
+++ b/gcc/ada/libgnarl/s-linux__riscv.ads
@@ -35,6 +35,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype int is Interfaces.C.int;
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__sparc.ads b/gcc/ada/libgnarl/s-linux__sparc.ads
index 47850fe..102e9ff 100644
--- a/gcc/ada/libgnarl/s-linux__sparc.ads
+++ b/gcc/ada/libgnarl/s-linux__sparc.ads
@@ -36,6 +36,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
package System.Linux is
pragma Preelaborate;
@@ -46,7 +47,8 @@ package System.Linux is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-linux__x32.ads b/gcc/ada/libgnarl/s-linux__x32.ads
index 29b1c0c..3281235 100644
--- a/gcc/ada/libgnarl/s-linux__x32.ads
+++ b/gcc/ada/libgnarl/s-linux__x32.ads
@@ -38,6 +38,8 @@
with Interfaces.C;
+with System.Parameters;
+
package System.Linux is
pragma Preelaborate;
@@ -46,12 +48,15 @@ package System.Linux is
----------
subtype suseconds_t is Long_Long_Integer;
- subtype time_t is Long_Long_Integer;
+ -- Note that suseconds_t is 64 bits.
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
tv_sec : time_t;
tv_nsec : Long_Long_Integer;
+ -- Note that tv_nsec is 64 bits.
end record;
pragma Convention (C, timespec);
diff --git a/gcc/ada/libgnarl/s-osinte__aix.ads b/gcc/ada/libgnarl/s-osinte__aix.ads
index 065876c..bab03d0 100644
--- a/gcc/ada/libgnarl/s-osinte__aix.ads
+++ b/gcc/ada/libgnarl/s-osinte__aix.ads
@@ -43,6 +43,8 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
with Interfaces.C.Extensions;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -540,7 +542,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__android.ads b/gcc/ada/libgnarl/s-osinte__android.ads
index 56bd134..27f7d9d 100644
--- a/gcc/ada/libgnarl/s-osinte__android.ads
+++ b/gcc/ada/libgnarl/s-osinte__android.ads
@@ -42,6 +42,7 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
with System.Linux;
with System.OS_Constants;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -593,7 +594,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__darwin.ads b/gcc/ada/libgnarl/s-osinte__darwin.ads
index a58f520..ac41d528 100644
--- a/gcc/ada/libgnarl/s-osinte__darwin.ads
+++ b/gcc/ada/libgnarl/s-osinte__darwin.ads
@@ -40,6 +40,7 @@
with Interfaces.C;
with System.OS_Constants;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -514,7 +515,8 @@ private
type pid_t is new int32_t;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__dragonfly.ads b/gcc/ada/libgnarl/s-osinte__dragonfly.ads
index 5ac4792..515e1b3 100644
--- a/gcc/ada/libgnarl/s-osinte__dragonfly.ads
+++ b/gcc/ada/libgnarl/s-osinte__dragonfly.ads
@@ -43,6 +43,8 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -633,7 +635,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
ts_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__freebsd.ads b/gcc/ada/libgnarl/s-osinte__freebsd.ads
index cbe8a6e..0dae1fb 100644
--- a/gcc/ada/libgnarl/s-osinte__freebsd.ads
+++ b/gcc/ada/libgnarl/s-osinte__freebsd.ads
@@ -43,6 +43,8 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -630,7 +632,8 @@ private
type pid_t is new int;
Self_PID : constant pid_t := 0;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
ts_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__gnu.ads b/gcc/ada/libgnarl/s-osinte__gnu.ads
index 99ee175..98eef86 100644
--- a/gcc/ada/libgnarl/s-osinte__gnu.ads
+++ b/gcc/ada/libgnarl/s-osinte__gnu.ads
@@ -39,6 +39,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
with Unchecked_Conversion;
package System.OS_Interface is
@@ -652,7 +653,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__hpux-dce.ads b/gcc/ada/libgnarl/s-osinte__hpux-dce.ads
index 8e04e63..ce8c5ab 100644
--- a/gcc/ada/libgnarl/s-osinte__hpux-dce.ads
+++ b/gcc/ada/libgnarl/s-osinte__hpux-dce.ads
@@ -42,6 +42,8 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -444,7 +446,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__hpux.ads b/gcc/ada/libgnarl/s-osinte__hpux.ads
index c92fbda..c94b84c 100644
--- a/gcc/ada/libgnarl/s-osinte__hpux.ads
+++ b/gcc/ada/libgnarl/s-osinte__hpux.ads
@@ -42,6 +42,8 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -514,7 +516,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
index 90e0116..de91ee8 100644
--- a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
+++ b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
@@ -39,6 +39,7 @@
-- Preelaborate. This package is designed to be a bottom-level (leaf) package
with Interfaces.C;
+with System.Parameters;
with Unchecked_Conversion;
package System.OS_Interface is
@@ -598,7 +599,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__linux.ads b/gcc/ada/libgnarl/s-osinte__linux.ads
index ca0bf1b..cda0f8e 100644
--- a/gcc/ada/libgnarl/s-osinte__linux.ads
+++ b/gcc/ada/libgnarl/s-osinte__linux.ads
@@ -51,6 +51,8 @@ package System.OS_Interface is
pragma Linker_Options ("-lpthread");
+ use type System.Linux.time_t;
+
subtype int is Interfaces.C.int;
subtype char is Interfaces.C.char;
subtype short is Interfaces.C.short;
diff --git a/gcc/ada/libgnarl/s-osinte__lynxos178e.ads b/gcc/ada/libgnarl/s-osinte__lynxos178e.ads
index f2a866b..4f38a53 100644
--- a/gcc/ada/libgnarl/s-osinte__lynxos178e.ads
+++ b/gcc/ada/libgnarl/s-osinte__lynxos178e.ads
@@ -43,6 +43,7 @@ with Ada.Unchecked_Conversion;
with Interfaces.C;
with System.Multiprocessors;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -539,7 +540,8 @@ private
type pid_t is new long;
- type time_t is new int64;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type suseconds_t is new int;
diff --git a/gcc/ada/libgnarl/s-osinte__qnx.ads b/gcc/ada/libgnarl/s-osinte__qnx.ads
index af326c4..28abfbe 100644
--- a/gcc/ada/libgnarl/s-osinte__qnx.ads
+++ b/gcc/ada/libgnarl/s-osinte__qnx.ads
@@ -40,6 +40,7 @@
with Ada.Unchecked_Conversion;
with Interfaces.C;
with System.OS_Constants;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -566,7 +567,8 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__rtems.ads b/gcc/ada/libgnarl/s-osinte__rtems.ads
index 6aae823..ffbfc3a 100644
--- a/gcc/ada/libgnarl/s-osinte__rtems.ads
+++ b/gcc/ada/libgnarl/s-osinte__rtems.ads
@@ -52,6 +52,7 @@
with Interfaces.C;
with System.OS_Constants;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -617,7 +618,8 @@ private
type pid_t is new int;
- type time_t is new Long_Long_Integer;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__solaris.ads b/gcc/ada/libgnarl/s-osinte__solaris.ads
index b2f4af4..29e1026 100644
--- a/gcc/ada/libgnarl/s-osinte__solaris.ads
+++ b/gcc/ada/libgnarl/s-osinte__solaris.ads
@@ -42,6 +42,8 @@ with Interfaces.C;
with Ada.Unchecked_Conversion;
+with System.Parameters;
+
package System.OS_Interface is
pragma Preelaborate;
@@ -523,7 +525,8 @@ private
type pid_t is new long;
- type time_t is new long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-osinte__vxworks.ads b/gcc/ada/libgnarl/s-osinte__vxworks.ads
index 5e30698..a2d5620 100644
--- a/gcc/ada/libgnarl/s-osinte__vxworks.ads
+++ b/gcc/ada/libgnarl/s-osinte__vxworks.ads
@@ -42,6 +42,7 @@ with Interfaces.C;
with System.VxWorks;
with System.VxWorks.Ext;
with System.Multiprocessors;
+with System.Parameters;
package System.OS_Interface is
pragma Preelaborate;
@@ -239,7 +240,11 @@ package System.OS_Interface is
-- Time --
----------
- type time_t is new unsigned_long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
+ -- Time_t here used to be unsigned to match the VxWorks header declaration.
+ -- The header declaration has changed in newer releases and is now signed
+ -- for applications.
type timespec is record
ts_sec : time_t;
diff --git a/gcc/ada/libgnarl/s-qnx.ads b/gcc/ada/libgnarl/s-qnx.ads
index 7f33d70..811c41c 100644
--- a/gcc/ada/libgnarl/s-qnx.ads
+++ b/gcc/ada/libgnarl/s-qnx.ads
@@ -37,6 +37,8 @@
with Interfaces.C;
+with System.Parameters;
+
package System.QNX is
pragma Preelaborate;
@@ -46,7 +48,8 @@ package System.QNX is
subtype long is Interfaces.C.long;
subtype suseconds_t is Interfaces.C.long;
- subtype time_t is Interfaces.C.long;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
subtype clockid_t is Interfaces.C.int;
type timespec is record
diff --git a/gcc/ada/libgnarl/s-tassta.adb b/gcc/ada/libgnarl/s-tassta.adb
index f18c76f..88850c2 100644
--- a/gcc/ada/libgnarl/s-tassta.adb
+++ b/gcc/ada/libgnarl/s-tassta.adb
@@ -910,12 +910,12 @@ package body System.Tasking.Stages is
Self_Id : constant Task_Id := Self;
begin
+ Initialization.Task_Lock (Self_Id);
+
if T.Common.State = Terminated then
-- It is not safe to call Abort_Defer or Write_Lock at this stage
- Initialization.Task_Lock (Self_Id);
-
Lock_RTS;
Initialization.Finalize_Attributes (T);
Initialization.Remove_From_All_Tasks_List (T);
@@ -930,6 +930,7 @@ package body System.Tasking.Stages is
-- upon termination.
T.Free_On_Termination := True;
+ Initialization.Task_Unlock (Self_Id);
end if;
end Free_Task;
diff --git a/gcc/ada/libgnat/a-cbdlli.adb b/gcc/ada/libgnat/a-cbdlli.adb
index bb92bda..143805e 100644
--- a/gcc/ada/libgnat/a-cbdlli.adb
+++ b/gcc/ada/libgnat/a-cbdlli.adb
@@ -312,7 +312,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1608,7 +1608,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cbhama.adb b/gcc/ada/libgnat/a-cbhama.adb
index 78a590f..26c01f5 100644
--- a/gcc/ada/libgnat/a-cbhama.adb
+++ b/gcc/ada/libgnat/a-cbhama.adb
@@ -213,7 +213,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -239,7 +239,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1028,7 +1028,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1053,7 +1053,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cbhase.adb b/gcc/ada/libgnat/a-cbhase.adb
index f8ca4d2..d6ab353 100644
--- a/gcc/ada/libgnat/a-cbhase.adb
+++ b/gcc/ada/libgnat/a-cbhase.adb
@@ -232,7 +232,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1643,7 +1643,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cbmutr.adb b/gcc/ada/libgnat/a-cbmutr.adb
index 714dea1..e80eb5c 100644
--- a/gcc/ada/libgnat/a-cbmutr.adb
+++ b/gcc/ada/libgnat/a-cbmutr.adb
@@ -600,7 +600,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => Container.Elements (Position.Node)'Access,
+ (Element => Container.Elements (Position.Node)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -2533,7 +2533,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => Container.Elements (Position.Node)'Access,
+ (Element => Container.Elements (Position.Node)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cborma.adb b/gcc/ada/libgnat/a-cborma.adb
index 67e6108..f26a1e3 100644
--- a/gcc/ada/libgnat/a-cborma.adb
+++ b/gcc/ada/libgnat/a-cborma.adb
@@ -420,7 +420,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -445,7 +445,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1417,7 +1417,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -1442,7 +1442,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cborse.adb b/gcc/ada/libgnat/a-cborse.adb
index 0b9e0cc..5c9a86e 100644
--- a/gcc/ada/libgnat/a-cborse.adb
+++ b/gcc/ada/libgnat/a-cborse.adb
@@ -420,7 +420,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -752,7 +752,7 @@ is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -943,7 +943,7 @@ is
N : Node_Type renames Container.Nodes (Position.Node);
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control =>
(Controlled with
Container.TC'Unrestricted_Access,
@@ -971,7 +971,7 @@ is
N : Node_Type renames Container.Nodes (Node);
begin
return R : constant Reference_Type :=
- (Element => N.Element'Access,
+ (Element => N.Element'Unchecked_Access,
Control =>
(Controlled with
Container.TC'Unrestricted_Access,
diff --git a/gcc/ada/libgnat/a-cdlili.adb b/gcc/ada/libgnat/a-cdlili.adb
index 73c1e6d..d989751 100644
--- a/gcc/ada/libgnat/a-cdlili.adb
+++ b/gcc/ada/libgnat/a-cdlili.adb
@@ -130,11 +130,6 @@ is
pragma Assert (Container.Last.Next = null);
pragma Assert (Container.Length > 0);
- Container.First := null;
- Container.Last := null;
- Container.Length := 0;
- Zero_Counts (Container.TC);
-
Container.First := new Node_Type'(Src.Element, null, null);
Container.Last := Container.First;
Container.Length := 1;
@@ -232,9 +227,7 @@ is
Container.Last := null;
Container.Length := 0;
- pragma Warnings (Off);
Free (X);
- pragma Warnings (On);
end Clear;
------------------------
@@ -682,68 +675,152 @@ is
procedure Sort (Container : in out List) is
- procedure Partition (Pivot : Node_Access; Back : Node_Access);
-
- procedure Sort (Front, Back : Node_Access);
-
- ---------------
- -- Partition --
- ---------------
+ type List_Descriptor is
+ record
+ First, Last : Node_Access;
+ Length : Count_Type;
+ end record;
+
+ function Merge_Sort (Arg : List_Descriptor) return List_Descriptor;
+ -- Sort list of given length using MergeSort; length must be >= 2.
+ -- As required by RM, the sort is stable.
+
+ ----------------
+ -- Merge_Sort --
+ ----------------
+
+ function Merge_Sort (Arg : List_Descriptor) return List_Descriptor
+ is
+ procedure Split_List
+ (Unsplit : List_Descriptor; Part1, Part2 : out List_Descriptor);
+ -- Split list into two parts for divide-and-conquer.
+ -- Unsplit.Length must be >= 2.
+
+ function Merge_Parts
+ (Part1, Part2 : List_Descriptor) return List_Descriptor;
+ -- Merge two sorted lists, preserving sorted property.
+
+ ----------------
+ -- Split_List --
+ ----------------
+
+ procedure Split_List
+ (Unsplit : List_Descriptor; Part1, Part2 : out List_Descriptor)
+ is
+ Rover : Node_Access := Unsplit.First;
+ Bump_Count : constant Count_Type := (Unsplit.Length - 1) / 2;
+ begin
+ for Iter in 1 .. Bump_Count loop
+ Rover := Rover.Next;
+ end loop;
+
+ Part1 := (First => Unsplit.First,
+ Last => Rover,
+ Length => Bump_Count + 1);
+
+ Part2 := (First => Rover.Next,
+ Last => Unsplit.Last,
+ Length => Unsplit.Length - Part1.Length);
+
+ -- Detach
+ Part1.Last.Next := null;
+ Part2.First.Prev := null;
+ end Split_List;
+
+ -----------------
+ -- Merge_Parts --
+ -----------------
+
+ function Merge_Parts
+ (Part1, Part2 : List_Descriptor) return List_Descriptor
+ is
+ Empty : constant List_Descriptor := (null, null, 0);
+
+ procedure Detach_First (Source : in out List_Descriptor;
+ Detached : out Node_Access);
+ -- Detach the first element from a non-empty list and
+ -- return the detached node via the Detached parameter.
+
+ ------------------
+ -- Detach_First --
+ ------------------
+
+ procedure Detach_First (Source : in out List_Descriptor;
+ Detached : out Node_Access) is
+ begin
+ Detached := Source.First;
+
+ if Source.Length = 1 then
+ Source := Empty;
+ else
+ Source := (Source.First.Next,
+ Source.Last,
+ Source.Length - 1);
+
+ Detached.Next.Prev := null;
+ Detached.Next := null;
+ end if;
+ end Detach_First;
+
+ P1 : List_Descriptor := Part1;
+ P2 : List_Descriptor := Part2;
+ Merged : List_Descriptor := Empty;
+
+ Take_From_P2 : Boolean;
+ Detached : Node_Access;
+
+ -- Start of processing for Merge_Parts
- procedure Partition (Pivot : Node_Access; Back : Node_Access) is
- Node : Node_Access;
+ begin
+ while (P1.Length /= 0) or (P2.Length /= 0) loop
+ if P1.Length = 0 then
+ Take_From_P2 := True;
+ elsif P2.Length = 0 then
+ Take_From_P2 := False;
+ else
+ -- If the compared elements are equal then Take_From_P2
+ -- must be False in order to ensure stability.
+
+ Take_From_P2 := P2.First.Element < P1.First.Element;
+ end if;
+
+ if Take_From_P2 then
+ Detach_First (P2, Detached);
+ else
+ Detach_First (P1, Detached);
+ end if;
+
+ if Merged.Length = 0 then
+ Merged := (First | Last => Detached, Length => 1);
+ else
+ Detached.Prev := Merged.Last;
+ Merged.Last.Next := Detached;
+ Merged.Last := Detached;
+ Merged.Length := Merged.Length + 1;
+ end if;
+ end loop;
+ return Merged;
+ end Merge_Parts;
+
+ -- Start of processing for Merge_Sort
begin
- Node := Pivot.Next;
- while Node /= Back loop
- if Node.Element < Pivot.Element then
- declare
- Prev : constant Node_Access := Node.Prev;
- Next : constant Node_Access := Node.Next;
-
- begin
- Prev.Next := Next;
-
- if Next = null then
- Container.Last := Prev;
- else
- Next.Prev := Prev;
- end if;
-
- Node.Next := Pivot;
- Node.Prev := Pivot.Prev;
-
- Pivot.Prev := Node;
-
- if Node.Prev = null then
- Container.First := Node;
- else
- Node.Prev.Next := Node;
- end if;
-
- Node := Next;
- end;
+ if Arg.Length < 2 then
+ -- already sorted
+ return Arg;
+ end if;
- else
- Node := Node.Next;
- end if;
- end loop;
- end Partition;
+ declare
+ Part1, Part2 : List_Descriptor;
+ begin
+ Split_List (Unsplit => Arg, Part1 => Part1, Part2 => Part2);
- ----------
- -- Sort --
- ----------
+ Part1 := Merge_Sort (Part1);
+ Part2 := Merge_Sort (Part2);
- procedure Sort (Front, Back : Node_Access) is
- Pivot : constant Node_Access :=
- (if Front = null then Container.First else Front.Next);
- begin
- if Pivot /= Back then
- Partition (Pivot, Back);
- Sort (Front, Pivot);
- Sort (Pivot, Back);
- end if;
- end Sort;
+ return Merge_Parts (Part1, Part2);
+ end;
+ end Merge_Sort;
-- Start of processing for Sort
@@ -761,9 +838,28 @@ is
-- element tampering by a generic actual subprogram.
declare
- Lock : With_Lock (Container.TC'Unchecked_Access);
+ Lock : With_Lock (Container.TC'Unchecked_Access);
+
+ Unsorted : constant List_Descriptor :=
+ (First => Container.First,
+ Last => Container.Last,
+ Length => Container.Length);
+
+ Sorted : List_Descriptor;
begin
- Sort (Front => null, Back => null);
+ -- If a call to the formal < operator references the container
+ -- during sorting, seeing an empty container seems preferable
+ -- to seeing an internally inconsistent container.
+ --
+ Container.First := null;
+ Container.Last := null;
+ Container.Length := 0;
+
+ Sorted := Merge_Sort (Unsorted);
+
+ Container.First := Sorted.First;
+ Container.Last := Sorted.Last;
+ Container.Length := Sorted.Length;
end;
pragma Assert (Container.First.Prev = null);
diff --git a/gcc/ada/libgnat/a-cfdlli.adb b/gcc/ada/libgnat/a-cfdlli.adb
index d96a8f6..b289def 100644
--- a/gcc/ada/libgnat/a-cfdlli.adb
+++ b/gcc/ada/libgnat/a-cfdlli.adb
@@ -188,6 +188,22 @@ is
Free (Container, X);
end Clear;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased List;
+ Position : Cursor) return not null access constant Element_Type
+ is
+ begin
+ if not Has_Element (Container => Container, Position => Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ return Container.Nodes (Position.Node).Element'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -1376,6 +1392,22 @@ is
return (Node => Container.Nodes (Position.Node).Prev);
end Previous;
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference
+ (Container : not null access List;
+ Position : Cursor) return not null access Element_Type
+ is
+ begin
+ if not Has_Element (Container.all, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ return Container.Nodes (Position.Node).Element'Access;
+ end Reference;
+
---------------------
-- Replace_Element --
---------------------
diff --git a/gcc/ada/libgnat/a-cfdlli.ads b/gcc/ada/libgnat/a-cfdlli.ads
index e3a2de6..8713d33 100644
--- a/gcc/ada/libgnat/a-cfdlli.ads
+++ b/gcc/ada/libgnat/a-cfdlli.ads
@@ -387,6 +387,53 @@ is
Model (Container),
P.Get (Positions (Container), Position));
+ function At_End (E : access constant List) return access constant List
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function At_End
+ (E : access constant Element_Type) return access constant Element_Type
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function Constant_Reference
+ (Container : aliased List;
+ Position : Cursor) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container, Position),
+ Post =>
+ Constant_Reference'Result.all =
+ Element (Model (Container), P.Get (Positions (Container), Position));
+
+ function Reference
+ (Container : not null access List;
+ Position : Cursor) return not null access Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container.all, Position),
+ Post =>
+ Length (Container.all) = Length (At_End (Container).all)
+
+ -- Cursors are preserved
+
+ and Positions (Container.all) = Positions (At_End (Container).all)
+
+ -- Container will have Result.all at position Position
+
+ and At_End (Reference'Result).all =
+ Element (Model (At_End (Container).all),
+ P.Get (Positions (At_End (Container).all), Position))
+
+ -- All other elements are preserved
+
+ and M.Equal_Except
+ (Model (Container.all),
+ Model (At_End (Container).all),
+ P.Get (Positions (At_End (Container).all), Position));
+
procedure Move (Target : in out List; Source : in out List) with
Global => null,
Pre => Target.Capacity >= Length (Source),
@@ -1609,7 +1656,7 @@ private
type Node_Type is record
Prev : Count_Type'Base := -1;
Next : Count_Type;
- Element : Element_Type;
+ Element : aliased Element_Type;
end record;
function "=" (L, R : Node_Type) return Boolean is abstract;
diff --git a/gcc/ada/libgnat/a-cfhama.adb b/gcc/ada/libgnat/a-cfhama.adb
index 17971b2..179b400 100644
--- a/gcc/ada/libgnat/a-cfhama.adb
+++ b/gcc/ada/libgnat/a-cfhama.adb
@@ -109,20 +109,21 @@ is
ENode : Count_Type;
begin
- Node := Left.First.Node;
+ Node := First (Left).Node;
while Node /= 0 loop
ENode :=
Find
(Container => Right,
- Key => Left.Nodes (Node).Key).Node;
+ Key => Left.Content.Nodes (Node).Key).Node;
if ENode = 0 or else
- Right.Nodes (ENode).Element /= Left.Nodes (Node).Element
+ Right.Content.Nodes (ENode).Element /=
+ Left.Content.Nodes (Node).Element
then
return False;
end if;
- Node := HT_Ops.Next (Left, Node);
+ Node := HT_Ops.Next (Left.Content, Node);
end loop;
return True;
@@ -145,7 +146,7 @@ is
--------------------
procedure Insert_Element (Source_Node : Count_Type) is
- N : Node_Type renames Source.Nodes (Source_Node);
+ N : Node_Type renames Source.Content.Nodes (Source_Node);
begin
Insert (Target, N.Key, N.Element);
end Insert_Element;
@@ -164,7 +165,7 @@ is
Clear (Target);
- Insert_Elements (Source);
+ Insert_Elements (Source.Content);
end Assign;
--------------
@@ -173,7 +174,7 @@ is
function Capacity (Container : Map) return Count_Type is
begin
- return Container.Nodes'Length;
+ return Container.Content.Nodes'Length;
end Capacity;
-----------
@@ -182,9 +183,44 @@ is
procedure Clear (Container : in out Map) is
begin
- HT_Ops.Clear (Container);
+ HT_Ops.Clear (Container.Content);
end Clear;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Position : Cursor) return not null access constant Element_Type
+ is
+ begin
+ if not Has_Element (Container, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ pragma Assert
+ (Vet (Container, Position),
+ "bad cursor in function Constant_Reference");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Constant_Reference;
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Key : Key_Type) return not null access constant Element_Type
+ is
+ Node : constant Count_Type := Find (Container, Key).Node;
+
+ begin
+ if Node = 0 then
+ raise Constraint_Error with
+ "no element available because key not in map";
+ end if;
+
+ return Container.Content.Nodes (Node).Element'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -214,18 +250,18 @@ is
raise Capacity_Error;
end if;
- Target.Length := Source.Length;
- Target.Free := Source.Free;
+ Target.Content.Length := Source.Content.Length;
+ Target.Content.Free := Source.Content.Free;
H := 1;
while H <= Source.Modulus loop
- Target.Buckets (H) := Source.Buckets (H);
+ Target.Content.Buckets (H) := Source.Content.Buckets (H);
H := H + 1;
end loop;
N := 1;
while N <= Source.Capacity loop
- Target.Nodes (N) := Source.Nodes (N);
+ Target.Content.Nodes (N) := Source.Content.Nodes (N);
N := N + 1;
end loop;
@@ -255,7 +291,7 @@ is
X : Count_Type;
begin
- Key_Ops.Delete_Key_Sans_Free (Container, Key, X);
+ Key_Ops.Delete_Key_Sans_Free (Container.Content, Key, X);
if X = 0 then
raise Constraint_Error with "attempt to delete key not in map";
@@ -273,7 +309,7 @@ is
pragma Assert (Vet (Container, Position), "bad cursor in Delete");
- HT_Ops.Delete_Node_Sans_Free (Container, Position.Node);
+ HT_Ops.Delete_Node_Sans_Free (Container.Content, Position.Node);
Free (Container, Position.Node);
Position := No_Element;
@@ -292,7 +328,7 @@ is
"no element available because key not in map";
end if;
- return Container.Nodes (Node).Element;
+ return Container.Content.Nodes (Node).Element;
end Element;
function Element (Container : Map; Position : Cursor) return Element_Type is
@@ -304,7 +340,7 @@ is
pragma Assert
(Vet (Container, Position), "bad cursor in function Element");
- return Container.Nodes (Position.Node).Element;
+ return Container.Content.Nodes (Position.Node).Element;
end Element;
---------------------
@@ -326,7 +362,7 @@ is
procedure Exclude (Container : in out Map; Key : Key_Type) is
X : Count_Type;
begin
- Key_Ops.Delete_Key_Sans_Free (Container, Key, X);
+ Key_Ops.Delete_Key_Sans_Free (Container.Content, Key, X);
Free (Container, X);
end Exclude;
@@ -335,7 +371,7 @@ is
----------
function Find (Container : Map; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Ops.Find (Container, Key);
+ Node : constant Count_Type := Key_Ops.Find (Container.Content, Key);
begin
if Node = 0 then
@@ -350,7 +386,7 @@ is
-----------
function First (Container : Map) return Cursor is
- Node : constant Count_Type := HT_Ops.First (Container);
+ Node : constant Count_Type := HT_Ops.First (Container.Content);
begin
if Node = 0 then
@@ -407,7 +443,7 @@ is
----------
function Keys (Container : Map) return K.Sequence is
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : K.Sequence;
begin
@@ -415,8 +451,8 @@ is
-- for their postconditions.
while Position /= 0 loop
- R := K.Add (R, Container.Nodes (Position).Key);
- Position := HT_Ops.Next (Container, Position);
+ R := K.Add (R, Container.Content.Nodes (Position).Key);
+ Position := HT_Ops.Next (Container.Content, Position);
end loop;
return R;
@@ -458,7 +494,7 @@ is
-----------
function Model (Container : Map) return M.Map is
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : M.Map;
begin
@@ -469,10 +505,10 @@ is
R :=
M.Add
(Container => R,
- New_Key => Container.Nodes (Position).Key,
- New_Item => Container.Nodes (Position).Element);
+ New_Key => Container.Content.Nodes (Position).Key,
+ New_Item => Container.Content.Nodes (Position).Element);
- Position := HT_Ops.Next (Container, Position);
+ Position := HT_Ops.Next (Container.Content, Position);
end loop;
return R;
@@ -484,7 +520,7 @@ is
function Positions (Container : Map) return P.Map is
I : Count_Type := 1;
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : P.Map;
begin
@@ -494,7 +530,7 @@ is
while Position /= 0 loop
R := P.Add (R, (Node => Position), I);
pragma Assert (P.Length (R) = I);
- Position := HT_Ops.Next (Container, Position);
+ Position := HT_Ops.Next (Container.Content, Position);
I := I + 1;
end loop;
@@ -511,8 +547,8 @@ is
begin
if X /= 0 then
pragma Assert (X <= HT.Capacity);
- HT.Nodes (X).Has_Element := False;
- HT_Ops.Free (HT, X);
+ HT.Content.Nodes (X).Has_Element := False;
+ HT_Ops.Free (HT.Content, X);
end if;
end Free;
@@ -525,8 +561,8 @@ is
new HT_Ops.Generic_Allocate (Set_Element);
begin
- Allocate (HT, Node);
- HT.Nodes (Node).Has_Element := True;
+ Allocate (HT.Content, Node);
+ HT.Content.Nodes (Node).Has_Element := True;
end Generic_Allocate;
-----------------
@@ -536,7 +572,7 @@ is
function Has_Element (Container : Map; Position : Cursor) return Boolean is
begin
if Position.Node = 0
- or else not Container.Nodes (Position.Node).Has_Element
+ or else not Container.Content.Nodes (Position.Node).Has_Element
then
return False;
else
@@ -570,7 +606,7 @@ is
if not Inserted then
declare
- N : Node_Type renames Container.Nodes (Position.Node);
+ N : Node_Type renames Container.Content.Nodes (Position.Node);
begin
N.Key := Key;
N.Element := New_Item;
@@ -625,7 +661,7 @@ is
-- Start of processing for Insert
begin
- Local_Insert (Container, Key, Position.Node, Inserted);
+ Local_Insert (Container.Content, Key, Position.Node, Inserted);
end Insert;
procedure Insert
@@ -668,7 +704,7 @@ is
pragma Assert (Vet (Container, Position), "bad cursor in function Key");
- return Container.Nodes (Position.Node).Key;
+ return Container.Content.Nodes (Position.Node).Key;
end Key;
------------
@@ -677,7 +713,7 @@ is
function Length (Container : Map) return Count_Type is
begin
- return Container.Length;
+ return Container.Content.Length;
end Length;
----------
@@ -688,7 +724,7 @@ is
(Target : in out Map;
Source : in out Map)
is
- NN : HT_Types.Nodes_Type renames Source.Nodes;
+ NN : HT_Types.Nodes_Type renames Source.Content.Nodes;
X : Count_Type;
Y : Count_Type;
@@ -704,17 +740,17 @@ is
Clear (Target);
- if Source.Length = 0 then
+ if Source.Content.Length = 0 then
return;
end if;
- X := HT_Ops.First (Source);
+ X := HT_Ops.First (Source.Content);
while X /= 0 loop
Insert (Target, NN (X).Key, NN (X).Element); -- optimize???
- Y := HT_Ops.Next (Source, X);
+ Y := HT_Ops.Next (Source.Content, X);
- HT_Ops.Delete_Node_Sans_Free (Source, X);
+ HT_Ops.Delete_Node_Sans_Free (Source.Content, X);
Free (Source, X);
X := Y;
@@ -743,7 +779,8 @@ is
pragma Assert (Vet (Container, Position), "bad cursor in function Next");
declare
- Node : constant Count_Type := HT_Ops.Next (Container, Position.Node);
+ Node : constant Count_Type :=
+ HT_Ops.Next (Container.Content, Position.Node);
begin
if Node = 0 then
@@ -759,6 +796,40 @@ is
Position := Next (Container, Position);
end Next;
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference
+ (Container : not null access Map;
+ Position : Cursor) return not null access Element_Type
+ is
+ begin
+ if not Has_Element (Container.all, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ pragma Assert
+ (Vet (Container.all, Position), "bad cursor in function Reference");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Reference;
+
+ function Reference
+ (Container : not null access Map;
+ Key : Key_Type) return not null access Element_Type
+ is
+ Node : constant Count_Type := Find (Container.all, Key).Node;
+
+ begin
+ if Node = 0 then
+ raise Constraint_Error with
+ "no element available because key not in map";
+ end if;
+
+ return Container.Content.Nodes (Node).Element'Access;
+ end Reference;
+
-------------
-- Replace --
-------------
@@ -768,7 +839,7 @@ is
Key : Key_Type;
New_Item : Element_Type)
is
- Node : constant Count_Type := Key_Ops.Find (Container, Key);
+ Node : constant Count_Type := Key_Ops.Find (Container.Content, Key);
begin
if Node = 0 then
@@ -776,7 +847,7 @@ is
end if;
declare
- N : Node_Type renames Container.Nodes (Node);
+ N : Node_Type renames Container.Content.Nodes (Node);
begin
N.Key := Key;
N.Element := New_Item;
@@ -801,7 +872,7 @@ is
pragma Assert
(Vet (Container, Position), "bad cursor in Replace_Element");
- Container.Nodes (Position.Node).Element := New_Item;
+ Container.Content.Nodes (Position.Node).Element := New_Item;
end Replace_Element;
----------------------
@@ -841,7 +912,7 @@ is
X : Count_Type;
begin
- if Container.Length = 0 then
+ if Container.Content.Length = 0 then
return False;
end if;
@@ -849,7 +920,7 @@ is
return False;
end if;
- if Container.Buckets'Length = 0 then
+ if Container.Content.Buckets'Length = 0 then
return False;
end if;
@@ -857,15 +928,17 @@ is
return False;
end if;
- if Container.Nodes (Position.Node).Next = Position.Node then
+ if Container.Content.Nodes (Position.Node).Next = Position.Node then
return False;
end if;
X :=
- Container.Buckets
- (Key_Ops.Index (Container, Container.Nodes (Position.Node).Key));
+ Container.Content.Buckets
+ (Key_Ops.Index
+ (Container.Content,
+ Container.Content.Nodes (Position.Node).Key));
- for J in 1 .. Container.Length loop
+ for J in 1 .. Container.Content.Length loop
if X = Position.Node then
return True;
end if;
@@ -874,14 +947,14 @@ is
return False;
end if;
- if X = Container.Nodes (X).Next then
+ if X = Container.Content.Nodes (X).Next then
-- Prevent unnecessary looping
return False;
end if;
- X := Container.Nodes (X).Next;
+ X := Container.Content.Nodes (X).Next;
end loop;
return False;
diff --git a/gcc/ada/libgnat/a-cfhama.ads b/gcc/ada/libgnat/a-cfhama.ads
index e9b0268..2b49c13 100644
--- a/gcc/ada/libgnat/a-cfhama.ads
+++ b/gcc/ada/libgnat/a-cfhama.ads
@@ -394,6 +394,95 @@ is
Model (Container)'Old,
Key (Container, Position));
+ function At_End
+ (E : not null access constant Map) return not null access constant Map
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function At_End
+ (E : access constant Element_Type) return access constant Element_Type
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Position : Cursor) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container, Position),
+ Post =>
+ Constant_Reference'Result.all =
+ Element (Model (Container), Key (Container, Position));
+
+ function Reference
+ (Container : not null access Map;
+ Position : Cursor) return not null access Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container.all, Position),
+ Post =>
+
+ -- Order of keys and cursors is preserved
+
+ Keys (At_End (Container).all) = Keys (Container.all)
+ and Positions (At_End (Container).all) = Positions (Container.all)
+
+ -- The value designated by the result of Reference is now associated
+ -- with the key at position Position in Container.
+
+ and Element (At_End (Container).all, Position) =
+ At_End (Reference'Result).all
+
+ -- Elements associated with other keys are preserved
+
+ and M.Same_Keys
+ (Model (At_End (Container).all),
+ Model (Container.all))
+ and M.Elements_Equal_Except
+ (Model (At_End (Container).all),
+ Model (Container.all),
+ Key (At_End (Container).all, Position));
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Key : Key_Type) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Contains (Container, Key),
+ Post =>
+ Constant_Reference'Result.all = Element (Model (Container), Key);
+
+ function Reference
+ (Container : not null access Map;
+ Key : Key_Type) return not null access Element_Type
+ with
+ Global => null,
+ Pre => Contains (Container.all, Key),
+ Post =>
+
+ -- Order of keys and cursors is preserved
+
+ Keys (At_End (Container).all) = Keys (Container.all)
+ and Positions (At_End (Container).all) = Positions (Container.all)
+
+ -- The value designated by the result of Reference is now associated
+ -- with Key in Container.
+
+ and Element (Model (At_End (Container).all), Key) =
+ At_End (Reference'Result).all
+
+ -- Elements associated with other keys are preserved
+
+ and M.Same_Keys
+ (Model (At_End (Container).all),
+ Model (Container.all))
+ and M.Elements_Equal_Except
+ (Model (At_End (Container).all),
+ Model (Container.all),
+ Key);
+
procedure Move (Target : in out Map; Source : in out Map) with
Global => null,
Pre => Target.Capacity >= Length (Source),
@@ -804,7 +893,7 @@ private
type Node_Type is record
Key : Key_Type;
- Element : Element_Type;
+ Element : aliased Element_Type;
Next : Count_Type;
Has_Element : Boolean := False;
end record;
@@ -812,8 +901,9 @@ private
package HT_Types is new
Ada.Containers.Hash_Tables.Generic_Bounded_Hash_Table_Types (Node_Type);
- type Map (Capacity : Count_Type; Modulus : Hash_Type) is
- new HT_Types.Hash_Table_Type (Capacity, Modulus) with null record;
+ type Map (Capacity : Count_Type; Modulus : Hash_Type) is record
+ Content : HT_Types.Hash_Table_Type (Capacity, Modulus);
+ end record;
Empty_Map : constant Map := (Capacity => 0, Modulus => 0, others => <>);
diff --git a/gcc/ada/libgnat/a-cfhase.adb b/gcc/ada/libgnat/a-cfhase.adb
index 3679ca4..cdb8a98 100644
--- a/gcc/ada/libgnat/a-cfhase.adb
+++ b/gcc/ada/libgnat/a-cfhase.adb
@@ -136,15 +136,16 @@ is
ENode :=
Find
(Container => Right,
- Item => Left.Nodes (Node).Element).Node;
+ Item => Left.Content.Nodes (Node).Element).Node;
if ENode = 0
- or else Right.Nodes (ENode).Element /= Left.Nodes (Node).Element
+ or else Right.Content.Nodes (ENode).Element /=
+ Left.Content.Nodes (Node).Element
then
return False;
end if;
- Node := HT_Ops.Next (Left, Node);
+ Node := HT_Ops.Next (Left.Content, Node);
end loop;
return True;
@@ -166,7 +167,7 @@ is
--------------------
procedure Insert_Element (Source_Node : Count_Type) is
- N : Node_Type renames Source.Nodes (Source_Node);
+ N : Node_Type renames Source.Content.Nodes (Source_Node);
X : Count_Type;
B : Boolean;
@@ -186,8 +187,8 @@ is
raise Storage_Error with "not enough capacity"; -- SE or CE? ???
end if;
- HT_Ops.Clear (Target);
- Insert_Elements (Source);
+ HT_Ops.Clear (Target.Content);
+ Insert_Elements (Source.Content);
end Assign;
--------------
@@ -196,7 +197,7 @@ is
function Capacity (Container : Set) return Count_Type is
begin
- return Container.Nodes'Length;
+ return Container.Content.Nodes'Length;
end Capacity;
-----------
@@ -205,9 +206,28 @@ is
procedure Clear (Container : in out Set) is
begin
- HT_Ops.Clear (Container);
+ HT_Ops.Clear (Container.Content);
end Clear;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Set;
+ Position : Cursor) return not null access constant Element_Type
+ is
+ begin
+ if not Has_Element (Container, Position) then
+ raise Constraint_Error with "Position cursor equals No_Element";
+ end if;
+
+ pragma Assert
+ (Vet (Container, Position), "bad cursor in function Element");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -237,18 +257,18 @@ is
raise Capacity_Error;
end if;
- Target.Length := Source.Length;
- Target.Free := Source.Free;
+ Target.Content.Length := Source.Content.Length;
+ Target.Content.Free := Source.Content.Free;
H := 1;
while H <= Source.Modulus loop
- Target.Buckets (H) := Source.Buckets (H);
+ Target.Content.Buckets (H) := Source.Content.Buckets (H);
H := H + 1;
end loop;
N := 1;
while N <= Source.Capacity loop
- Target.Nodes (N) := Source.Nodes (N);
+ Target.Content.Nodes (N) := Source.Content.Nodes (N);
N := N + 1;
end loop;
@@ -278,7 +298,7 @@ is
X : Count_Type;
begin
- Element_Keys.Delete_Key_Sans_Free (Container, Item, X);
+ Element_Keys.Delete_Key_Sans_Free (Container.Content, Item, X);
if X = 0 then
raise Constraint_Error with "attempt to delete element not in set";
@@ -295,7 +315,7 @@ is
pragma Assert (Vet (Container, Position), "bad cursor in Delete");
- HT_Ops.Delete_Node_Sans_Free (Container, Position.Node);
+ HT_Ops.Delete_Node_Sans_Free (Container.Content, Position.Node);
Free (Container, Position.Node);
Position := No_Element;
@@ -311,8 +331,8 @@ is
Src_Node : Count_Type;
Tgt_Node : Count_Type;
- TN : Nodes_Type renames Target.Nodes;
- SN : Nodes_Type renames Source.Nodes;
+ TN : Nodes_Type renames Target.Content.Nodes;
+ SN : Nodes_Type renames Source.Content.Nodes;
begin
if Target'Address = Source'Address then
@@ -320,44 +340,45 @@ is
return;
end if;
- Src_Length := Source.Length;
+ Src_Length := Source.Content.Length;
if Src_Length = 0 then
return;
end if;
- if Src_Length >= Target.Length then
- Tgt_Node := HT_Ops.First (Target);
+ if Src_Length >= Target.Content.Length then
+ Tgt_Node := HT_Ops.First (Target.Content);
while Tgt_Node /= 0 loop
- if Element_Keys.Find (Source, TN (Tgt_Node).Element) /= 0 then
+ if Element_Keys.Find (Source.Content, TN (Tgt_Node).Element) /= 0
+ then
declare
X : constant Count_Type := Tgt_Node;
begin
- Tgt_Node := HT_Ops.Next (Target, Tgt_Node);
- HT_Ops.Delete_Node_Sans_Free (Target, X);
+ Tgt_Node := HT_Ops.Next (Target.Content, Tgt_Node);
+ HT_Ops.Delete_Node_Sans_Free (Target.Content, X);
Free (Target, X);
end;
else
- Tgt_Node := HT_Ops.Next (Target, Tgt_Node);
+ Tgt_Node := HT_Ops.Next (Target.Content, Tgt_Node);
end if;
end loop;
return;
else
- Src_Node := HT_Ops.First (Source);
+ Src_Node := HT_Ops.First (Source.Content);
Src_Last := 0;
end if;
while Src_Node /= Src_Last loop
- Tgt_Node := Element_Keys.Find (Target, SN (Src_Node).Element);
+ Tgt_Node := Element_Keys.Find (Target.Content, SN (Src_Node).Element);
if Tgt_Node /= 0 then
- HT_Ops.Delete_Node_Sans_Free (Target, Tgt_Node);
+ HT_Ops.Delete_Node_Sans_Free (Target.Content, Tgt_Node);
Free (Target, Tgt_Node);
end if;
- Src_Node := HT_Ops.Next (Source, Src_Node);
+ Src_Node := HT_Ops.Next (Source.Content, Src_Node);
end loop;
end Difference;
@@ -373,7 +394,7 @@ is
procedure Process (L_Node : Count_Type) is
B : Boolean;
- E : Element_Type renames Left.Nodes (L_Node).Element;
+ E : Element_Type renames Left.Content.Nodes (L_Node).Element;
X : Count_Type;
begin
@@ -386,7 +407,7 @@ is
-- Start of processing for Difference
begin
- Iterate (Left);
+ Iterate (Left.Content);
end Difference;
function Difference (Left : Set; Right : Set) return Set is
@@ -403,7 +424,7 @@ is
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
C := Length (Left);
@@ -430,7 +451,7 @@ is
pragma Assert
(Vet (Container, Position), "bad cursor in function Element");
- return Container.Nodes (Position.Node).Element;
+ return Container.Content.Nodes (Position.Node).Element;
end Element;
---------------------
@@ -479,7 +500,7 @@ is
-- Start of processing for Equivalent_Sets
begin
- return Is_Equivalent (Left, Right);
+ return Is_Equivalent (Left.Content, Right.Content);
end Equivalent_Sets;
---------------------
@@ -501,7 +522,7 @@ is
procedure Exclude (Container : in out Set; Item : Element_Type) is
X : Count_Type;
begin
- Element_Keys.Delete_Key_Sans_Free (Container, Item, X);
+ Element_Keys.Delete_Key_Sans_Free (Container.Content, Item, X);
Free (Container, X);
end Exclude;
@@ -513,7 +534,8 @@ is
(Container : Set;
Item : Element_Type) return Cursor
is
- Node : constant Count_Type := Element_Keys.Find (Container, Item);
+ Node : constant Count_Type :=
+ Element_Keys.Find (Container.Content, Item);
begin
if Node = 0 then
@@ -528,7 +550,7 @@ is
-----------
function First (Container : Set) return Cursor is
- Node : constant Count_Type := HT_Ops.First (Container);
+ Node : constant Count_Type := HT_Ops.First (Container.Content);
begin
if Node = 0 then
@@ -632,7 +654,7 @@ is
--------------
function Elements (Container : Set) return E.Sequence is
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : E.Sequence;
begin
@@ -640,8 +662,8 @@ is
-- for their postconditions.
while Position /= 0 loop
- R := E.Add (R, Container.Nodes (Position).Element);
- Position := HT_Ops.Next (Container, Position);
+ R := E.Add (R, Container.Content.Nodes (Position).Element);
+ Position := HT_Ops.Next (Container.Content, Position);
end loop;
return R;
@@ -710,7 +732,7 @@ is
-----------
function Model (Container : Set) return M.Set is
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : M.Set;
begin
@@ -721,9 +743,9 @@ is
R :=
M.Add
(Container => R,
- Item => Container.Nodes (Position).Element);
+ Item => Container.Content.Nodes (Position).Element);
- Position := HT_Ops.Next (Container, Position);
+ Position := HT_Ops.Next (Container.Content, Position);
end loop;
return R;
@@ -735,7 +757,7 @@ is
function Positions (Container : Set) return P.Map is
I : Count_Type := 1;
- Position : Count_Type := HT_Ops.First (Container);
+ Position : Count_Type := HT_Ops.First (Container.Content);
R : P.Map;
begin
@@ -745,7 +767,7 @@ is
while Position /= 0 loop
R := P.Add (R, (Node => Position), I);
pragma Assert (P.Length (R) = I);
- Position := HT_Ops.Next (Container, Position);
+ Position := HT_Ops.Next (Container.Content, Position);
I := I + 1;
end loop;
@@ -762,8 +784,8 @@ is
begin
if X /= 0 then
pragma Assert (X <= HT.Capacity);
- HT.Nodes (X).Has_Element := False;
- HT_Ops.Free (HT, X);
+ HT.Content.Nodes (X).Has_Element := False;
+ HT_Ops.Free (HT.Content, X);
end if;
end Free;
@@ -774,8 +796,8 @@ is
procedure Generic_Allocate (HT : in out Set; Node : out Count_Type) is
procedure Allocate is new HT_Ops.Generic_Allocate (Set_Element);
begin
- Allocate (HT, Node);
- HT.Nodes (Node).Has_Element := True;
+ Allocate (HT.Content, Node);
+ HT.Content.Nodes (Node).Has_Element := True;
end Generic_Allocate;
package body Generic_Keys with SPARK_Mode => Off is
@@ -821,7 +843,7 @@ is
X : Count_Type;
begin
- Key_Keys.Delete_Key_Sans_Free (Container, Key, X);
+ Key_Keys.Delete_Key_Sans_Free (Container.Content, Key, X);
if X = 0 then
raise Constraint_Error with "attempt to delete key not in set";
@@ -845,7 +867,7 @@ is
raise Constraint_Error with "key not in map";
end if;
- return Container.Nodes (Node).Element;
+ return Container.Content.Nodes (Node).Element;
end Element;
-------------------------
@@ -867,7 +889,7 @@ is
procedure Exclude (Container : in out Set; Key : Key_Type) is
X : Count_Type;
begin
- Key_Keys.Delete_Key_Sans_Free (Container, Key, X);
+ Key_Keys.Delete_Key_Sans_Free (Container.Content, Key, X);
Free (Container, X);
end Exclude;
@@ -879,7 +901,7 @@ is
(Container : Set;
Key : Key_Type) return Cursor
is
- Node : constant Count_Type := Key_Keys.Find (Container, Key);
+ Node : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
return (if Node = 0 then No_Element else (Node => Node));
end Find;
@@ -927,7 +949,7 @@ is
(Vet (Container, Position), "bad cursor in function Key");
declare
- N : Node_Type renames Container.Nodes (Position.Node);
+ N : Node_Type renames Container.Content.Nodes (Position.Node);
begin
return Key (N.Element);
end;
@@ -942,14 +964,14 @@ is
Key : Key_Type;
New_Item : Element_Type)
is
- Node : constant Count_Type := Key_Keys.Find (Container, Key);
+ Node : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
if Node = 0 then
raise Constraint_Error with "attempt to replace key not in set";
end if;
- Replace_Element (Container, Node, New_Item);
+ Replace_Element (Container.Content, Node, New_Item);
end Replace;
end Generic_Keys;
@@ -961,7 +983,7 @@ is
function Has_Element (Container : Set; Position : Cursor) return Boolean is
begin
if Position.Node = 0
- or else not Container.Nodes (Position.Node).Has_Element
+ or else not Container.Content.Nodes (Position.Node).Has_Element
then
return False;
end if;
@@ -990,7 +1012,7 @@ is
Insert (Container, New_Item, Position, Inserted);
if not Inserted then
- Container.Nodes (Position.Node).Element := New_Item;
+ Container.Content.Nodes (Position.Node).Element := New_Item;
end if;
end Include;
@@ -1062,7 +1084,7 @@ is
-- Start of processing for Insert
begin
- Local_Insert (Container, New_Item, Node, Inserted);
+ Local_Insert (Container.Content, New_Item, Node, Inserted);
end Insert;
------------------
@@ -1071,29 +1093,29 @@ is
procedure Intersection (Target : in out Set; Source : Set) is
Tgt_Node : Count_Type;
- TN : Nodes_Type renames Target.Nodes;
+ TN : Nodes_Type renames Target.Content.Nodes;
begin
if Target'Address = Source'Address then
return;
end if;
- if Source.Length = 0 then
+ if Source.Content.Length = 0 then
Clear (Target);
return;
end if;
- Tgt_Node := HT_Ops.First (Target);
+ Tgt_Node := HT_Ops.First (Target.Content);
while Tgt_Node /= 0 loop
if Find (Source, TN (Tgt_Node).Element).Node /= 0 then
- Tgt_Node := HT_Ops.Next (Target, Tgt_Node);
+ Tgt_Node := HT_Ops.Next (Target.Content, Tgt_Node);
else
declare
X : constant Count_Type := Tgt_Node;
begin
- Tgt_Node := HT_Ops.Next (Target, Tgt_Node);
- HT_Ops.Delete_Node_Sans_Free (Target, X);
+ Tgt_Node := HT_Ops.Next (Target.Content, Tgt_Node);
+ HT_Ops.Delete_Node_Sans_Free (Target.Content, X);
Free (Target, X);
end;
end if;
@@ -1111,7 +1133,7 @@ is
-------------
procedure Process (L_Node : Count_Type) is
- E : Element_Type renames Left.Nodes (L_Node).Element;
+ E : Element_Type renames Left.Content.Nodes (L_Node).Element;
X : Count_Type;
B : Boolean;
@@ -1125,7 +1147,7 @@ is
-- Start of processing for Intersection
begin
- Iterate (Left);
+ Iterate (Left.Content);
end Intersection;
function Intersection (Left : Set; Right : Set) return Set is
@@ -1134,7 +1156,7 @@ is
begin
if Left'Address = Right'Address then
- return Left.Copy;
+ return Copy (Left);
end if;
C := Count_Type'Min (Length (Left), Length (Right)); -- ???
@@ -1162,7 +1184,7 @@ is
function Is_In (HT : Set; Key : Node_Type) return Boolean is
begin
- return Element_Keys.Find (HT, Key.Element) /= 0;
+ return Element_Keys.Find (HT.Content, Key.Element) /= 0;
end Is_In;
---------------
@@ -1171,7 +1193,7 @@ is
function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
Subset_Node : Count_Type;
- Subset_Nodes : Nodes_Type renames Subset.Nodes;
+ Subset_Nodes : Nodes_Type renames Subset.Content.Nodes;
begin
if Subset'Address = Of_Set'Address then
@@ -1194,7 +1216,7 @@ is
end if;
end;
- Subset_Node := HT_Ops.Next (Subset, Subset_Node);
+ Subset_Node := HT_Ops.Next (Subset.Content, Subset_Node);
end loop;
return True;
@@ -1206,7 +1228,7 @@ is
function Length (Container : Set) return Count_Type is
begin
- return Container.Length;
+ return Container.Content.Length;
end Length;
----------
@@ -1216,7 +1238,7 @@ is
-- Comments???
procedure Move (Target : in out Set; Source : in out Set) is
- NN : HT_Types.Nodes_Type renames Source.Nodes;
+ NN : HT_Types.Nodes_Type renames Source.Content.Nodes;
X, Y : Count_Type;
begin
@@ -1231,17 +1253,17 @@ is
Clear (Target);
- if Source.Length = 0 then
+ if Source.Content.Length = 0 then
return;
end if;
- X := HT_Ops.First (Source);
+ X := HT_Ops.First (Source.Content);
while X /= 0 loop
Insert (Target, NN (X).Element); -- optimize???
- Y := HT_Ops.Next (Source, X);
+ Y := HT_Ops.Next (Source.Content, X);
- HT_Ops.Delete_Node_Sans_Free (Source, X);
+ HT_Ops.Delete_Node_Sans_Free (Source.Content, X);
Free (Source, X);
X := Y;
@@ -1269,7 +1291,7 @@ is
pragma Assert (Vet (Container, Position), "bad cursor in Next");
- return (Node => HT_Ops.Next (Container, Position.Node));
+ return (Node => HT_Ops.Next (Container.Content, Position.Node));
end Next;
procedure Next (Container : Set; Position : in out Cursor) is
@@ -1283,7 +1305,7 @@ is
function Overlap (Left, Right : Set) return Boolean is
Left_Node : Count_Type;
- Left_Nodes : Nodes_Type renames Left.Nodes;
+ Left_Nodes : Nodes_Type renames Left.Content.Nodes;
begin
if Length (Right) = 0 or Length (Left) = 0 then
@@ -1305,7 +1327,7 @@ is
end if;
end;
- Left_Node := HT_Ops.Next (Left, Left_Node);
+ Left_Node := HT_Ops.Next (Left.Content, Left_Node);
end loop;
return False;
@@ -1316,14 +1338,15 @@ is
-------------
procedure Replace (Container : in out Set; New_Item : Element_Type) is
- Node : constant Count_Type := Element_Keys.Find (Container, New_Item);
+ Node : constant Count_Type :=
+ Element_Keys.Find (Container.Content, New_Item);
begin
if Node = 0 then
raise Constraint_Error with "attempt to replace element not in set";
end if;
- Container.Nodes (Node).Element := New_Item;
+ Container.Content.Nodes (Node).Element := New_Item;
end Replace;
---------------------
@@ -1343,7 +1366,7 @@ is
pragma Assert
(Vet (Container, Position), "bad cursor in Replace_Element");
- Replace_Element (Container, Position.Node, New_Item);
+ Replace_Element (Container.Content, Position.Node, New_Item);
end Replace_Element;
----------------------
@@ -1394,7 +1417,7 @@ is
procedure Process (Source_Node : Count_Type) is
B : Boolean;
- N : Node_Type renames Source.Nodes (Source_Node);
+ N : Node_Type renames Source.Content.Nodes (Source_Node);
X : Count_Type;
begin
@@ -1419,7 +1442,7 @@ is
return;
end if;
- Iterate (Source);
+ Iterate (Source.Content);
end Symmetric_Difference;
function Symmetric_Difference (Left : Set; Right : Set) return Set is
@@ -1432,11 +1455,11 @@ is
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
if Length (Left) = 0 then
- return Right.Copy;
+ return Copy (Right);
end if;
C := Length (Left) + Length (Right);
@@ -1478,7 +1501,7 @@ is
-------------
procedure Process (Src_Node : Count_Type) is
- N : Node_Type renames Source.Nodes (Src_Node);
+ N : Node_Type renames Source.Content.Nodes (Src_Node);
E : Element_Type renames N.Element;
X : Count_Type;
@@ -1495,7 +1518,7 @@ is
return;
end if;
- Iterate (Source);
+ Iterate (Source.Content);
end Union;
function Union (Left : Set; Right : Set) return Set is
@@ -1504,15 +1527,15 @@ is
begin
if Left'Address = Right'Address then
- return Left.Copy;
+ return Copy (Left);
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
if Length (Left) = 0 then
- return Right.Copy;
+ return Copy (Right);
end if;
C := Length (Left) + Length (Right);
@@ -1535,11 +1558,11 @@ is
declare
S : Set renames Container;
- N : Nodes_Type renames S.Nodes;
+ N : Nodes_Type renames S.Content.Nodes;
X : Count_Type;
begin
- if S.Length = 0 then
+ if S.Content.Length = 0 then
return False;
end if;
@@ -1551,9 +1574,10 @@ is
return False;
end if;
- X := S.Buckets (Element_Keys.Index (S, N (Position.Node).Element));
+ X := S.Content.Buckets
+ (Element_Keys.Index (S.Content, N (Position.Node).Element));
- for J in 1 .. S.Length loop
+ for J in 1 .. S.Content.Length loop
if X = Position.Node then
return True;
end if;
diff --git a/gcc/ada/libgnat/a-cfhase.ads b/gcc/ada/libgnat/a-cfhase.ads
index 5d57863..9bcd8ce 100644
--- a/gcc/ada/libgnat/a-cfhase.ads
+++ b/gcc/ada/libgnat/a-cfhase.ads
@@ -515,6 +515,16 @@ is
Position => Position)
and Positions (Container) = Positions (Container)'Old;
+ function Constant_Reference
+ (Container : aliased Set;
+ Position : Cursor) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container, Position),
+ Post =>
+ Constant_Reference'Result.all =
+ E.Get (Elements (Container), P.Get (Positions (Container), Position));
+
procedure Move (Target : in out Set; Source : in out Set) with
Global => null,
Pre => Target.Capacity >= Length (Source),
@@ -1462,7 +1472,7 @@ private
type Node_Type is
record
- Element : Element_Type;
+ Element : aliased Element_Type;
Next : Count_Type;
Has_Element : Boolean := False;
end record;
@@ -1470,8 +1480,9 @@ private
package HT_Types is new
Ada.Containers.Hash_Tables.Generic_Bounded_Hash_Table_Types (Node_Type);
- type Set (Capacity : Count_Type; Modulus : Hash_Type) is
- new HT_Types.Hash_Table_Type (Capacity, Modulus) with null record;
+ type Set (Capacity : Count_Type; Modulus : Hash_Type) is record
+ Content : HT_Types.Hash_Table_Type (Capacity, Modulus);
+ end record;
use HT_Types;
diff --git a/gcc/ada/libgnat/a-cfinve.adb b/gcc/ada/libgnat/a-cfinve.adb
index 6ab4935..d0c7e82 100644
--- a/gcc/ada/libgnat/a-cfinve.adb
+++ b/gcc/ada/libgnat/a-cfinve.adb
@@ -184,6 +184,28 @@ is
Free (Container.Elements_Ptr);
end Clear;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Vector;
+ Index : Index_Type) return not null access constant Element_Type
+ is
+ begin
+ if Index > Container.Last then
+ raise Constraint_Error with "Index is out of range";
+ end if;
+
+ declare
+ II : constant Int'Base := Int (Index) - Int (No_Index);
+ I : constant Capacity_Range := Capacity_Range (II);
+
+ begin
+ return Constant_Reference (Elemsc (Container) (I));
+ end;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -1180,6 +1202,32 @@ is
Insert (Container, Index_Type'First, New_Item, Count);
end Prepend;
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference
+ (Container : not null access Vector;
+ Index : Index_Type) return not null access Element_Type
+ is
+ begin
+ if Index > Container.Last then
+ raise Constraint_Error with "Index is out of range";
+ end if;
+
+ declare
+ II : constant Int'Base := Int (Index) - Int (No_Index);
+ I : constant Capacity_Range := Capacity_Range (II);
+
+ begin
+ if Container.Elements_Ptr = null then
+ return Reference (Container.Elements (I)'Access);
+ else
+ return Reference (Container.Elements_Ptr (I)'Access);
+ end if;
+ end;
+ end Reference;
+
---------------------
-- Replace_Element --
---------------------
diff --git a/gcc/ada/libgnat/a-cfinve.ads b/gcc/ada/libgnat/a-cfinve.ads
index 37dde92..9b95437 100644
--- a/gcc/ada/libgnat/a-cfinve.ads
+++ b/gcc/ada/libgnat/a-cfinve.ads
@@ -311,6 +311,48 @@ is
Right => Model (Container),
Position => Index);
+ function At_End (E : access constant Vector) return access constant Vector
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function At_End
+ (E : access constant Element_Type) return access constant Element_Type
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function Constant_Reference
+ (Container : aliased Vector;
+ Index : Index_Type) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Index in First_Index (Container) .. Last_Index (Container),
+ Post =>
+ Constant_Reference'Result.all = Element (Model (Container), Index);
+
+ function Reference
+ (Container : not null access Vector;
+ Index : Index_Type) return not null access Element_Type
+ with
+ Global => null,
+ Pre =>
+ Index in First_Index (Container.all) .. Last_Index (Container.all),
+ Post =>
+ Length (Container.all) = Length (At_End (Container).all)
+
+ -- Container will have Result.all at index Index
+
+ and At_End (Reference'Result).all =
+ Element (Model (At_End (Container).all), Index)
+
+ -- All other elements are preserved
+
+ and M.Equal_Except
+ (Left => Model (Container.all),
+ Right => Model (At_End (Container).all),
+ Position => Index);
+
procedure Insert
(Container : in out Vector;
Before : Extended_Index;
@@ -909,7 +951,7 @@ private
use Holders;
subtype Array_Index is Capacity_Range range 1 .. Capacity_Range'Last;
- type Elements_Array is array (Array_Index range <>) of Holder;
+ type Elements_Array is array (Array_Index range <>) of aliased Holder;
function "=" (L, R : Elements_Array) return Boolean is abstract;
type Elements_Array_Ptr is access all Elements_Array;
diff --git a/gcc/ada/libgnat/a-cforma.adb b/gcc/ada/libgnat/a-cforma.adb
index f384619..45f9be7 100644
--- a/gcc/ada/libgnat/a-cforma.adb
+++ b/gcc/ada/libgnat/a-cforma.adb
@@ -133,19 +133,20 @@ is
return True;
end if;
- Lst := Next (Left, Last (Left).Node);
+ Lst := Next (Left.Content, Last (Left).Node);
Node := First (Left).Node;
while Node /= Lst loop
- ENode := Find (Right, Left.Nodes (Node).Key).Node;
+ ENode := Find (Right, Left.Content.Nodes (Node).Key).Node;
if ENode = 0 or else
- Left.Nodes (Node).Element /= Right.Nodes (ENode).Element
+ Left.Content.Nodes (Node).Element /=
+ Right.Content.Nodes (ENode).Element
then
return False;
end if;
- Node := Next (Left, Node);
+ Node := Next (Left.Content, Node);
end loop;
return True;
@@ -166,7 +167,7 @@ is
--------------------
procedure Append_Element (Source_Node : Count_Type) is
- SN : Node_Type renames Source.Nodes (Source_Node);
+ SN : Node_Type renames Source.Content.Nodes (Source_Node);
procedure Set_Element (Node : in out Node_Type);
pragma Inline (Set_Element);
@@ -193,7 +194,7 @@ is
function New_Node return Count_Type is
Result : Count_Type;
begin
- Allocate (Target, Result);
+ Allocate (Target.Content, Result);
return Result;
end New_Node;
@@ -213,7 +214,7 @@ is
begin
Unconditional_Insert_Avec_Hint
- (Tree => Target,
+ (Tree => Target.Content,
Hint => 0,
Key => SN.Key,
Node => Target_Node);
@@ -230,8 +231,8 @@ is
raise Storage_Error with "not enough capacity"; -- SE or CE? ???
end if;
- Tree_Operations.Clear_Tree (Target);
- Append_Elements (Source);
+ Tree_Operations.Clear_Tree (Target.Content);
+ Append_Elements (Source.Content);
end Assign;
-------------
@@ -239,7 +240,7 @@ is
-------------
function Ceiling (Container : Map; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Ops.Ceiling (Container, Key);
+ Node : constant Count_Type := Key_Ops.Ceiling (Container.Content, Key);
begin
if Node = 0 then
@@ -255,7 +256,7 @@ is
procedure Clear (Container : in out Map) is
begin
- Tree_Operations.Clear_Tree (Container);
+ Tree_Operations.Clear_Tree (Container.Content);
end Clear;
-----------
@@ -267,6 +268,40 @@ is
return Node.Color;
end Color;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Position : Cursor) return not null access constant Element_Type
+ is
+ begin
+ if not Has_Element (Container, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ pragma Assert (Vet (Container.Content, Position.Node),
+ "bad cursor in function Constant_Reference");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Constant_Reference;
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Key : Key_Type) return not null access constant Element_Type
+ is
+ Node : constant Node_Access := Find (Container, Key).Node;
+
+ begin
+ if Node = 0 then
+ raise Constraint_Error with
+ "no element available because key not in map";
+ end if;
+
+ return Container.Content.Nodes (Node).Element'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -291,33 +326,33 @@ is
return Target : Map (Count_Type'Max (Source.Capacity, Capacity)) do
if Length (Source) > 0 then
- Target.Length := Source.Length;
- Target.Root := Source.Root;
- Target.First := Source.First;
- Target.Last := Source.Last;
- Target.Free := Source.Free;
+ Target.Content.Length := Source.Content.Length;
+ Target.Content.Root := Source.Content.Root;
+ Target.Content.First := Source.Content.First;
+ Target.Content.Last := Source.Content.Last;
+ Target.Content.Free := Source.Content.Free;
while Node <= Source.Capacity loop
- Target.Nodes (Node).Element :=
- Source.Nodes (Node).Element;
- Target.Nodes (Node).Key :=
- Source.Nodes (Node).Key;
- Target.Nodes (Node).Parent :=
- Source.Nodes (Node).Parent;
- Target.Nodes (Node).Left :=
- Source.Nodes (Node).Left;
- Target.Nodes (Node).Right :=
- Source.Nodes (Node).Right;
- Target.Nodes (Node).Color :=
- Source.Nodes (Node).Color;
- Target.Nodes (Node).Has_Element :=
- Source.Nodes (Node).Has_Element;
+ Target.Content.Nodes (Node).Element :=
+ Source.Content.Nodes (Node).Element;
+ Target.Content.Nodes (Node).Key :=
+ Source.Content.Nodes (Node).Key;
+ Target.Content.Nodes (Node).Parent :=
+ Source.Content.Nodes (Node).Parent;
+ Target.Content.Nodes (Node).Left :=
+ Source.Content.Nodes (Node).Left;
+ Target.Content.Nodes (Node).Right :=
+ Source.Content.Nodes (Node).Right;
+ Target.Content.Nodes (Node).Color :=
+ Source.Content.Nodes (Node).Color;
+ Target.Content.Nodes (Node).Has_Element :=
+ Source.Content.Nodes (Node).Has_Element;
Node := Node + 1;
end loop;
while Node <= Target.Capacity loop
N := Node;
- Formal_Ordered_Maps.Free (Tree => Target, X => N);
+ Free (Tree => Target, X => N);
Node := Node + 1;
end loop;
end if;
@@ -335,25 +370,25 @@ is
"Position cursor of Delete has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"Position cursor of Delete is bad");
- Tree_Operations.Delete_Node_Sans_Free (Container,
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content,
Position.Node);
- Formal_Ordered_Maps.Free (Container, Position.Node);
+ Free (Container, Position.Node);
Position := No_Element;
end Delete;
procedure Delete (Container : in out Map; Key : Key_Type) is
- X : constant Node_Access := Key_Ops.Find (Container, Key);
+ X : constant Node_Access := Key_Ops.Find (Container.Content, Key);
begin
if X = 0 then
raise Constraint_Error with "key not in map";
end if;
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Maps.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end Delete;
------------------
@@ -364,8 +399,8 @@ is
X : constant Node_Access := First (Container).Node;
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Maps.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Delete_First;
@@ -377,8 +412,8 @@ is
X : constant Node_Access := Last (Container).Node;
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Maps.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Delete_Last;
@@ -393,10 +428,10 @@ is
"Position cursor of function Element has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"Position cursor of function Element is bad");
- return Container.Nodes (Position.Node).Element;
+ return Container.Content.Nodes (Position.Node).Element;
end Element;
@@ -408,7 +443,7 @@ is
raise Constraint_Error with "key not in map";
end if;
- return Container.Nodes (Node).Element;
+ return Container.Content.Nodes (Node).Element;
end Element;
---------------------
@@ -431,11 +466,11 @@ is
-------------
procedure Exclude (Container : in out Map; Key : Key_Type) is
- X : constant Node_Access := Key_Ops.Find (Container, Key);
+ X : constant Node_Access := Key_Ops.Find (Container.Content, Key);
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Maps.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Exclude;
@@ -444,7 +479,7 @@ is
----------
function Find (Container : Map; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Ops.Find (Container, Key);
+ Node : constant Count_Type := Key_Ops.Find (Container.Content, Key);
begin
if Node = 0 then
@@ -464,7 +499,7 @@ is
return No_Element;
end if;
- return (Node => Container.First);
+ return (Node => Container.Content.First);
end First;
-------------------
@@ -477,7 +512,7 @@ is
raise Constraint_Error with "map is empty";
end if;
- return Container.Nodes (First (Container).Node).Element;
+ return Container.Content.Nodes (First (Container).Node).Element;
end First_Element;
---------------
@@ -490,7 +525,7 @@ is
raise Constraint_Error with "map is empty";
end if;
- return Container.Nodes (First (Container).Node).Key;
+ return Container.Content.Nodes (First (Container).Node).Key;
end First_Key;
-----------
@@ -498,7 +533,7 @@ is
-----------
function Floor (Container : Map; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Ops.Floor (Container, Key);
+ Node : constant Count_Type := Key_Ops.Floor (Container.Content, Key);
begin
if Node = 0 then
@@ -602,7 +637,7 @@ is
----------
function Keys (Container : Map) return K.Sequence is
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : K.Sequence;
begin
@@ -610,8 +645,8 @@ is
-- for their postconditions.
while Position /= 0 loop
- R := K.Add (R, Container.Nodes (Position).Key);
- Position := Tree_Operations.Next (Container, Position);
+ R := K.Add (R, Container.Content.Nodes (Position).Key);
+ Position := Tree_Operations.Next (Container.Content, Position);
end loop;
return R;
@@ -628,7 +663,7 @@ is
-----------
function Model (Container : Map) return M.Map is
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : M.Map;
begin
@@ -639,10 +674,10 @@ is
R :=
M.Add
(Container => R,
- New_Key => Container.Nodes (Position).Key,
- New_Item => Container.Nodes (Position).Element);
+ New_Key => Container.Content.Nodes (Position).Key,
+ New_Item => Container.Content.Nodes (Position).Element);
- Position := Tree_Operations.Next (Container, Position);
+ Position := Tree_Operations.Next (Container.Content, Position);
end loop;
return R;
@@ -701,7 +736,7 @@ is
function Positions (Container : Map) return P.Map is
I : Count_Type := 1;
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : P.Map;
begin
@@ -711,7 +746,7 @@ is
while Position /= 0 loop
R := P.Add (R, (Node => Position), I);
pragma Assert (P.Length (R) = I);
- Position := Tree_Operations.Next (Container, Position);
+ Position := Tree_Operations.Next (Container.Content, Position);
I := I + 1;
end loop;
@@ -729,8 +764,8 @@ is
X : Count_Type)
is
begin
- Tree.Nodes (X).Has_Element := False;
- Tree_Operations.Free (Tree, X);
+ Tree.Content.Nodes (X).Has_Element := False;
+ Tree_Operations.Free (Tree.Content, X);
end Free;
----------------------
@@ -758,7 +793,7 @@ is
return False;
end if;
- return Container.Nodes (Position.Node).Has_Element;
+ return Container.Content.Nodes (Position.Node).Has_Element;
end Has_Element;
-------------
@@ -778,7 +813,7 @@ is
if not Inserted then
declare
- N : Node_Type renames Container.Nodes (Position.Node);
+ N : Node_Type renames Container.Content.Nodes (Position.Node);
begin
N.Key := Key;
N.Element := New_Item;
@@ -819,7 +854,7 @@ is
X : Node_Access;
begin
- Allocate_Node (Container, X);
+ Allocate_Node (Container.Content, X);
return X;
end New_Node;
@@ -827,7 +862,7 @@ is
begin
Insert_Sans_Hint
- (Container,
+ (Container.Content,
Key,
Position.Node,
Inserted);
@@ -895,10 +930,10 @@ is
"Position cursor of function Key has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"Position cursor of function Key is bad");
- return Container.Nodes (Position.Node).Key;
+ return Container.Content.Nodes (Position.Node).Key;
end Key;
----------
@@ -911,7 +946,7 @@ is
return No_Element;
end if;
- return (Node => Container.Last);
+ return (Node => Container.Content.Last);
end Last;
------------------
@@ -924,7 +959,7 @@ is
raise Constraint_Error with "map is empty";
end if;
- return Container.Nodes (Last (Container).Node).Element;
+ return Container.Content.Nodes (Last (Container).Node).Element;
end Last_Element;
--------------
@@ -937,7 +972,7 @@ is
raise Constraint_Error with "map is empty";
end if;
- return Container.Nodes (Last (Container).Node).Key;
+ return Container.Content.Nodes (Last (Container).Node).Key;
end Last_Key;
--------------
@@ -955,7 +990,7 @@ is
function Length (Container : Map) return Count_Type is
begin
- return Container.Length;
+ return Container.Content.Length;
end Length;
----------
@@ -963,7 +998,7 @@ is
----------
procedure Move (Target : in out Map; Source : in out Map) is
- NN : Tree_Types.Nodes_Type renames Source.Nodes;
+ NN : Tree_Types.Nodes_Type renames Source.Content.Nodes;
X : Node_Access;
begin
@@ -989,7 +1024,7 @@ is
Insert (Target, NN (X).Key, NN (X).Element); -- optimize???
- Tree_Operations.Delete_Node_Sans_Free (Source, X);
+ Tree_Operations.Delete_Node_Sans_Free (Source.Content, X);
Formal_Ordered_Maps.Free (Source, X);
end loop;
end Move;
@@ -1013,10 +1048,10 @@ is
raise Constraint_Error;
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Next");
- return (Node => Tree_Operations.Next (Container, Position.Node));
+ return (Node => Tree_Operations.Next (Container.Content, Position.Node));
end Next;
------------
@@ -1047,12 +1082,12 @@ is
raise Constraint_Error;
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Previous");
declare
Node : constant Count_Type :=
- Tree_Operations.Previous (Container, Position.Node);
+ Tree_Operations.Previous (Container.Content, Position.Node);
begin
if Node = 0 then
@@ -1063,6 +1098,41 @@ is
end;
end Previous;
+ --------------
+ -- Reference --
+ --------------
+
+ function Reference
+ (Container : not null access Map;
+ Position : Cursor) return not null access Element_Type
+ is
+ begin
+ if not Has_Element (Container.all, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ pragma Assert
+ (Vet (Container.Content, Position.Node),
+ "bad cursor in function Reference");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Reference;
+
+ function Reference
+ (Container : not null access Map;
+ Key : Key_Type) return not null access Element_Type
+ is
+ Node : constant Count_Type := Find (Container.all, Key).Node;
+
+ begin
+ if Node = 0 then
+ raise Constraint_Error with
+ "no element available because key not in map";
+ end if;
+
+ return Container.Content.Nodes (Node).Element'Access;
+ end Reference;
+
-------------
-- Replace --
-------------
@@ -1074,7 +1144,7 @@ is
is
begin
declare
- Node : constant Node_Access := Key_Ops.Find (Container, Key);
+ Node : constant Node_Access := Key_Ops.Find (Container.Content, Key);
begin
if Node = 0 then
@@ -1082,7 +1152,7 @@ is
end if;
declare
- N : Node_Type renames Container.Nodes (Node);
+ N : Node_Type renames Container.Content.Nodes (Node);
begin
N.Key := Key;
N.Element := New_Item;
@@ -1105,10 +1175,10 @@ is
"Position cursor of Replace_Element has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"Position cursor of Replace_Element is bad");
- Container.Nodes (Position.Node).Element := New_Item;
+ Container.Content.Nodes (Position.Node).Element := New_Item;
end Replace_Element;
---------------
diff --git a/gcc/ada/libgnat/a-cforma.ads b/gcc/ada/libgnat/a-cforma.ads
index d32727e..a1cad03 100644
--- a/gcc/ada/libgnat/a-cforma.ads
+++ b/gcc/ada/libgnat/a-cforma.ads
@@ -400,6 +400,95 @@ is
Model (Container)'Old,
Key (Container, Position));
+ function At_End
+ (E : not null access constant Map) return not null access constant Map
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function At_End
+ (E : access constant Element_Type) return access constant Element_Type
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Position : Cursor) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container, Position),
+ Post =>
+ Constant_Reference'Result.all =
+ Element (Model (Container), Key (Container, Position));
+
+ function Reference
+ (Container : not null access Map;
+ Position : Cursor) return not null access Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container.all, Position),
+ Post =>
+
+ -- Order of keys and cursors is preserved
+
+ Keys (At_End (Container).all) = Keys (Container.all)
+ and Positions (At_End (Container).all) = Positions (Container.all)
+
+ -- The value designated by the result of Reference is now associated
+ -- with the key at position Position in Container.
+
+ and Element (At_End (Container).all, Position) =
+ At_End (Reference'Result).all
+
+ -- Elements associated with other keys are preserved
+
+ and M.Same_Keys
+ (Model (At_End (Container).all),
+ Model (Container.all))
+ and M.Elements_Equal_Except
+ (Model (At_End (Container).all),
+ Model (Container.all),
+ Key (At_End (Container).all, Position));
+
+ function Constant_Reference
+ (Container : aliased Map;
+ Key : Key_Type) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Contains (Container, Key),
+ Post =>
+ Constant_Reference'Result.all = Element (Model (Container), Key);
+
+ function Reference
+ (Container : not null access Map;
+ Key : Key_Type) return not null access Element_Type
+ with
+ Global => null,
+ Pre => Contains (Container.all, Key),
+ Post =>
+
+ -- Order of keys and cursors is preserved
+
+ Keys (At_End (Container).all) = Keys (Container.all)
+ and Positions (At_End (Container).all) = Positions (Container.all)
+
+ -- The value designated by the result of Reference is now associated
+ -- with Key in Container.
+
+ and Element (Model (At_End (Container).all), Key) =
+ At_End (Reference'Result).all
+
+ -- Elements associated with other keys are preserved
+
+ and M.Same_Keys
+ (Model (At_End (Container).all),
+ Model (Container.all))
+ and M.Elements_Equal_Except
+ (Model (At_End (Container).all),
+ Model (Container.all),
+ Key);
+
procedure Move (Target : in out Map; Source : in out Map) with
Global => null,
Pre => Target.Capacity >= Length (Source),
@@ -1045,14 +1134,15 @@ private
Right : Node_Access := 0;
Color : Red_Black_Trees.Color_Type := Red;
Key : Key_Type;
- Element : Element_Type;
+ Element : aliased Element_Type;
end record;
package Tree_Types is
new Ada.Containers.Red_Black_Trees.Generic_Bounded_Tree_Types (Node_Type);
- type Map (Capacity : Count_Type) is
- new Tree_Types.Tree_Type (Capacity) with null record;
+ type Map (Capacity : Count_Type) is record
+ Content : Tree_Types.Tree_Type (Capacity);
+ end record;
Empty_Map : constant Map := (Capacity => 0, others => <>);
diff --git a/gcc/ada/libgnat/a-cforse.adb b/gcc/ada/libgnat/a-cforse.adb
index e5525b9..7c45e4f 100644
--- a/gcc/ada/libgnat/a-cforse.adb
+++ b/gcc/ada/libgnat/a-cforse.adb
@@ -81,6 +81,10 @@ is
-- Comments needed???
+ procedure Assign
+ (Target : in out Tree_Types.Tree_Type;
+ Source : Tree_Types.Tree_Type);
+
generic
with procedure Set_Element (Node : in out Node_Type);
procedure Generic_Allocate
@@ -90,13 +94,13 @@ is
procedure Free (Tree : in out Set; X : Count_Type);
procedure Insert_Sans_Hint
- (Container : in out Set;
+ (Container : in out Tree_Types.Tree_Type;
New_Item : Element_Type;
Node : out Count_Type;
Inserted : out Boolean);
procedure Insert_With_Hint
- (Dst_Set : in out Set;
+ (Dst_Set : in out Tree_Types.Tree_Type;
Dst_Hint : Count_Type;
Src_Node : Node_Type;
Dst_Node : out Count_Type);
@@ -141,7 +145,7 @@ is
package Set_Ops is
new Red_Black_Trees.Generic_Bounded_Set_Operations
(Tree_Operations => Tree_Operations,
- Set_Type => Set,
+ Set_Type => Tree_Types.Tree_Type,
Assign => Assign,
Insert_With_Hint => Insert_With_Hint,
Is_Less => Is_Less_Node_Node);
@@ -164,18 +168,19 @@ is
return True;
end if;
- Lst := Next (Left, Last (Left).Node);
+ Lst := Next (Left.Content, Last (Left).Node);
Node := First (Left).Node;
while Node /= Lst loop
- ENode := Find (Right, Left.Nodes (Node).Element).Node;
+ ENode := Find (Right, Left.Content.Nodes (Node).Element).Node;
if ENode = 0
- or else Left.Nodes (Node).Element /= Right.Nodes (ENode).Element
+ or else Left.Content.Nodes (Node).Element /=
+ Right.Content.Nodes (ENode).Element
then
return False;
end if;
- Node := Next (Left, Node);
+ Node := Next (Left.Content, Node);
end loop;
return True;
@@ -185,7 +190,10 @@ is
-- Assign --
------------
- procedure Assign (Target : in out Set; Source : Set) is
+ procedure Assign
+ (Target : in out Tree_Types.Tree_Type;
+ Source : Tree_Types.Tree_Type)
+ is
procedure Append_Element (Source_Node : Count_Type);
procedure Append_Elements is
@@ -267,12 +275,18 @@ is
Append_Elements (Source);
end Assign;
+ procedure Assign (Target : in out Set; Source : Set) is
+ begin
+ Assign (Target.Content, Source.Content);
+ end Assign;
+
-------------
-- Ceiling --
-------------
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Count_Type := Element_Keys.Ceiling (Container, Item);
+ Node : constant Count_Type :=
+ Element_Keys.Ceiling (Container.Content, Item);
begin
if Node = 0 then
@@ -288,7 +302,7 @@ is
procedure Clear (Container : in out Set) is
begin
- Tree_Operations.Clear_Tree (Container);
+ Tree_Operations.Clear_Tree (Container.Content);
end Clear;
-----------
@@ -300,6 +314,25 @@ is
return Node.Color;
end Color;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Set;
+ Position : Cursor) return not null access constant Element_Type
+ is
+ begin
+ if not Has_Element (Container, Position) then
+ raise Constraint_Error with "Position cursor has no element";
+ end if;
+
+ pragma Assert (Vet (Container.Content, Position.Node),
+ "bad cursor in Element");
+
+ return Container.Content.Nodes (Position.Node).Element'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -327,32 +360,32 @@ is
end if;
if Length (Source) > 0 then
- Target.Length := Source.Length;
- Target.Root := Source.Root;
- Target.First := Source.First;
- Target.Last := Source.Last;
- Target.Free := Source.Free;
+ Target.Content.Length := Source.Content.Length;
+ Target.Content.Root := Source.Content.Root;
+ Target.Content.First := Source.Content.First;
+ Target.Content.Last := Source.Content.Last;
+ Target.Content.Free := Source.Content.Free;
Node := 1;
while Node <= Source.Capacity loop
- Target.Nodes (Node).Element :=
- Source.Nodes (Node).Element;
- Target.Nodes (Node).Parent :=
- Source.Nodes (Node).Parent;
- Target.Nodes (Node).Left :=
- Source.Nodes (Node).Left;
- Target.Nodes (Node).Right :=
- Source.Nodes (Node).Right;
- Target.Nodes (Node).Color :=
- Source.Nodes (Node).Color;
- Target.Nodes (Node).Has_Element :=
- Source.Nodes (Node).Has_Element;
+ Target.Content.Nodes (Node).Element :=
+ Source.Content.Nodes (Node).Element;
+ Target.Content.Nodes (Node).Parent :=
+ Source.Content.Nodes (Node).Parent;
+ Target.Content.Nodes (Node).Left :=
+ Source.Content.Nodes (Node).Left;
+ Target.Content.Nodes (Node).Right :=
+ Source.Content.Nodes (Node).Right;
+ Target.Content.Nodes (Node).Color :=
+ Source.Content.Nodes (Node).Color;
+ Target.Content.Nodes (Node).Has_Element :=
+ Source.Content.Nodes (Node).Has_Element;
Node := Node + 1;
end loop;
while Node <= Target.Capacity loop
N := Node;
- Formal_Ordered_Sets.Free (Tree => Target, X => N);
+ Free (Tree => Target, X => N);
Node := Node + 1;
end loop;
end if;
@@ -370,25 +403,25 @@ is
raise Constraint_Error with "Position cursor has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Delete");
- Tree_Operations.Delete_Node_Sans_Free (Container,
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content,
Position.Node);
- Formal_Ordered_Sets.Free (Container, Position.Node);
+ Free (Container, Position.Node);
Position := No_Element;
end Delete;
procedure Delete (Container : in out Set; Item : Element_Type) is
- X : constant Count_Type := Element_Keys.Find (Container, Item);
+ X : constant Count_Type := Element_Keys.Find (Container.Content, Item);
begin
if X = 0 then
raise Constraint_Error with "attempt to delete element not in set";
end if;
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end Delete;
------------------
@@ -396,11 +429,11 @@ is
------------------
procedure Delete_First (Container : in out Set) is
- X : constant Count_Type := Container.First;
+ X : constant Count_Type := Container.Content.First;
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Delete_First;
@@ -409,11 +442,11 @@ is
-----------------
procedure Delete_Last (Container : in out Set) is
- X : constant Count_Type := Container.Last;
+ X : constant Count_Type := Container.Content.Last;
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Delete_Last;
@@ -423,7 +456,7 @@ is
procedure Difference (Target : in out Set; Source : Set) is
begin
- Set_Ops.Set_Difference (Target, Source);
+ Set_Ops.Set_Difference (Target.Content, Source.Content);
end Difference;
function Difference (Left, Right : Set) return Set is
@@ -437,11 +470,12 @@ is
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
return S : Set (Length (Left)) do
- Assign (S, Set_Ops.Set_Difference (Left, Right));
+ Assign
+ (S.Content, Set_Ops.Set_Difference (Left.Content, Right.Content));
end return;
end Difference;
@@ -455,10 +489,10 @@ is
raise Constraint_Error with "Position cursor has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Element");
- return Container.Nodes (Position.Node).Element;
+ return Container.Content.Nodes (Position.Node).Element;
end Element;
-------------------------
@@ -506,7 +540,7 @@ is
-- Start of processing for Equivalent_Sets
begin
- return Is_Equivalent (Left, Right);
+ return Is_Equivalent (Left.Content, Right.Content);
end Equivalent_Sets;
-------------
@@ -514,11 +548,11 @@ is
-------------
procedure Exclude (Container : in out Set; Item : Element_Type) is
- X : constant Count_Type := Element_Keys.Find (Container, Item);
+ X : constant Count_Type := Element_Keys.Find (Container.Content, Item);
begin
if X /= 0 then
- Tree_Operations.Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Tree_Operations.Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Exclude;
@@ -527,7 +561,8 @@ is
----------
function Find (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Count_Type := Element_Keys.Find (Container, Item);
+ Node : constant Count_Type :=
+ Element_Keys.Find (Container.Content, Item);
begin
if Node = 0 then
@@ -547,7 +582,7 @@ is
return No_Element;
end if;
- return (Node => Container.First);
+ return (Node => Container.Content.First);
end First;
-------------------
@@ -562,7 +597,7 @@ is
end if;
declare
- N : Tree_Types.Nodes_Type renames Container.Nodes;
+ N : Tree_Types.Nodes_Type renames Container.Content.Nodes;
begin
return N (Fst).Element;
end;
@@ -575,7 +610,8 @@ is
function Floor (Container : Set; Item : Element_Type) return Cursor is
begin
declare
- Node : constant Count_Type := Element_Keys.Floor (Container, Item);
+ Node : constant Count_Type :=
+ Element_Keys.Floor (Container.Content, Item);
begin
if Node = 0 then
@@ -748,7 +784,7 @@ is
--------------
function Elements (Container : Set) return E.Sequence is
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : E.Sequence;
begin
@@ -756,8 +792,8 @@ is
-- for their postconditions.
while Position /= 0 loop
- R := E.Add (R, Container.Nodes (Position).Element);
- Position := Tree_Operations.Next (Container, Position);
+ R := E.Add (R, Container.Content.Nodes (Position).Element);
+ Position := Tree_Operations.Next (Container.Content, Position);
end loop;
return R;
@@ -873,7 +909,7 @@ is
-----------
function Model (Container : Set) return M.Set is
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : M.Set;
begin
@@ -884,9 +920,9 @@ is
R :=
M.Add
(Container => R,
- Item => Container.Nodes (Position).Element);
+ Item => Container.Content.Nodes (Position).Element);
- Position := Tree_Operations.Next (Container, Position);
+ Position := Tree_Operations.Next (Container.Content, Position);
end loop;
return R;
@@ -898,7 +934,7 @@ is
function Positions (Container : Set) return P.Map is
I : Count_Type := 1;
- Position : Count_Type := Container.First;
+ Position : Count_Type := Container.Content.First;
R : P.Map;
begin
@@ -908,7 +944,7 @@ is
while Position /= 0 loop
R := P.Add (R, (Node => Position), I);
pragma Assert (P.Length (R) = I);
- Position := Tree_Operations.Next (Container, Position);
+ Position := Tree_Operations.Next (Container.Content, Position);
I := I + 1;
end loop;
@@ -923,8 +959,8 @@ is
procedure Free (Tree : in out Set; X : Count_Type) is
begin
- Tree.Nodes (X).Has_Element := False;
- Tree_Operations.Free (Tree, X);
+ Tree.Content.Nodes (X).Has_Element := False;
+ Tree_Operations.Free (Tree.Content, X);
end Free;
----------------------
@@ -978,7 +1014,8 @@ is
-------------
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Keys.Ceiling (Container, Key);
+ Node : constant Count_Type :=
+ Key_Keys.Ceiling (Container.Content, Key);
begin
if Node = 0 then
@@ -1002,15 +1039,15 @@ is
------------
procedure Delete (Container : in out Set; Key : Key_Type) is
- X : constant Count_Type := Key_Keys.Find (Container, Key);
+ X : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
if X = 0 then
raise Constraint_Error with "attempt to delete key not in set";
end if;
- Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end Delete;
-------------
@@ -1018,7 +1055,7 @@ is
-------------
function Element (Container : Set; Key : Key_Type) return Element_Type is
- Node : constant Count_Type := Key_Keys.Find (Container, Key);
+ Node : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
if Node = 0 then
@@ -1026,7 +1063,7 @@ is
end if;
declare
- N : Tree_Types.Nodes_Type renames Container.Nodes;
+ N : Tree_Types.Nodes_Type renames Container.Content.Nodes;
begin
return N (Node).Element;
end;
@@ -1052,11 +1089,11 @@ is
-------------
procedure Exclude (Container : in out Set; Key : Key_Type) is
- X : constant Count_Type := Key_Keys.Find (Container, Key);
+ X : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
if X /= 0 then
- Delete_Node_Sans_Free (Container, X);
- Formal_Ordered_Sets.Free (Container, X);
+ Delete_Node_Sans_Free (Container.Content, X);
+ Free (Container, X);
end if;
end Exclude;
@@ -1065,7 +1102,7 @@ is
----------
function Find (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Keys.Find (Container, Key);
+ Node : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
return (if Node = 0 then No_Element else (Node => Node));
end Find;
@@ -1075,7 +1112,7 @@ is
-----------
function Floor (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Count_Type := Key_Keys.Floor (Container, Key);
+ Node : constant Count_Type := Key_Keys.Floor (Container.Content, Key);
begin
return (if Node = 0 then No_Element else (Node => Node));
end Floor;
@@ -1225,11 +1262,11 @@ is
"Position cursor has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Key");
declare
- N : Tree_Types.Nodes_Type renames Container.Nodes;
+ N : Tree_Types.Nodes_Type renames Container.Content.Nodes;
begin
return Key (N (Position.Node).Element);
end;
@@ -1244,7 +1281,7 @@ is
Key : Key_Type;
New_Item : Element_Type)
is
- Node : constant Count_Type := Key_Keys.Find (Container, Key);
+ Node : constant Count_Type := Key_Keys.Find (Container.Content, Key);
begin
if not Has_Element (Container, (Node => Node)) then
raise Constraint_Error with
@@ -1265,7 +1302,7 @@ is
if Position.Node = 0 then
return False;
else
- return Container.Nodes (Position.Node).Has_Element;
+ return Container.Content.Nodes (Position.Node).Has_Element;
end if;
end Has_Element;
@@ -1282,7 +1319,7 @@ is
if not Inserted then
declare
- N : Tree_Types.Nodes_Type renames Container.Nodes;
+ N : Tree_Types.Nodes_Type renames Container.Content.Nodes;
begin
N (Position.Node).Element := New_Item;
end;
@@ -1300,7 +1337,7 @@ is
Inserted : out Boolean)
is
begin
- Insert_Sans_Hint (Container, New_Item, Position.Node, Inserted);
+ Insert_Sans_Hint (Container.Content, New_Item, Position.Node, Inserted);
end Insert;
procedure Insert
@@ -1324,7 +1361,7 @@ is
----------------------
procedure Insert_Sans_Hint
- (Container : in out Set;
+ (Container : in out Tree_Types.Tree_Type;
New_Item : Element_Type;
Node : out Count_Type;
Inserted : out Boolean)
@@ -1377,7 +1414,7 @@ is
----------------------
procedure Insert_With_Hint
- (Dst_Set : in out Set;
+ (Dst_Set : in out Tree_Types.Tree_Type;
Dst_Hint : Count_Type;
Src_Node : Node_Type;
Dst_Node : out Count_Type)
@@ -1439,17 +1476,18 @@ is
procedure Intersection (Target : in out Set; Source : Set) is
begin
- Set_Ops.Set_Intersection (Target, Source);
+ Set_Ops.Set_Intersection (Target.Content, Source.Content);
end Intersection;
function Intersection (Left, Right : Set) return Set is
begin
if Left'Address = Right'Address then
- return Left.Copy;
+ return Copy (Left);
end if;
return S : Set (Count_Type'Min (Length (Left), Length (Right))) do
- Assign (S, Set_Ops.Set_Intersection (Left, Right));
+ Assign (S.Content,
+ Set_Ops.Set_Intersection (Left.Content, Right.Content));
end return;
end Intersection;
@@ -1503,7 +1541,7 @@ is
function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
begin
- return Set_Ops.Set_Subset (Subset, Of_Set => Of_Set);
+ return Set_Ops.Set_Subset (Subset.Content, Of_Set => Of_Set.Content);
end Is_Subset;
----------
@@ -1514,7 +1552,7 @@ is
begin
return (if Length (Container) = 0
then No_Element
- else (Node => Container.Last));
+ else (Node => Container.Content.Last));
end Last;
------------------
@@ -1528,7 +1566,7 @@ is
end if;
declare
- N : Tree_Types.Nodes_Type renames Container.Nodes;
+ N : Tree_Types.Nodes_Type renames Container.Content.Nodes;
begin
return N (Last (Container).Node).Element;
end;
@@ -1549,7 +1587,7 @@ is
function Length (Container : Set) return Count_Type is
begin
- return Container.Length;
+ return Container.Content.Length;
end Length;
----------
@@ -1557,7 +1595,7 @@ is
----------
procedure Move (Target : in out Set; Source : in out Set) is
- N : Tree_Types.Nodes_Type renames Source.Nodes;
+ N : Tree_Types.Nodes_Type renames Source.Content.Nodes;
X : Count_Type;
begin
@@ -1573,13 +1611,13 @@ is
Clear (Target);
loop
- X := Source.First;
+ X := Source.Content.First;
exit when X = 0;
Insert (Target, N (X).Element); -- optimize???
- Tree_Operations.Delete_Node_Sans_Free (Source, X);
- Formal_Ordered_Sets.Free (Source, X);
+ Tree_Operations.Delete_Node_Sans_Free (Source.Content, X);
+ Free (Source, X);
end loop;
end Move;
@@ -1597,9 +1635,9 @@ is
raise Constraint_Error;
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Next");
- return (Node => Tree_Operations.Next (Container, Position.Node));
+ return (Node => Tree_Operations.Next (Container.Content, Position.Node));
end Next;
procedure Next (Container : Set; Position : in out Cursor) is
@@ -1613,7 +1651,7 @@ is
function Overlap (Left, Right : Set) return Boolean is
begin
- return Set_Ops.Set_Overlap (Left, Right);
+ return Set_Ops.Set_Overlap (Left.Content, Right.Content);
end Overlap;
------------
@@ -1639,12 +1677,12 @@ is
raise Constraint_Error;
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Previous");
declare
Node : constant Count_Type :=
- Tree_Operations.Previous (Container, Position.Node);
+ Tree_Operations.Previous (Container.Content, Position.Node);
begin
return (if Node = 0 then No_Element else (Node => Node));
end;
@@ -1660,7 +1698,8 @@ is
-------------
procedure Replace (Container : in out Set; New_Item : Element_Type) is
- Node : constant Count_Type := Element_Keys.Find (Container, New_Item);
+ Node : constant Count_Type :=
+ Element_Keys.Find (Container.Content, New_Item);
begin
if Node = 0 then
@@ -1668,7 +1707,7 @@ is
"attempt to replace element not in set";
end if;
- Container.Nodes (Node).Element := New_Item;
+ Container.Content.Nodes (Node).Element := New_Item;
end Replace;
---------------------
@@ -1696,7 +1735,7 @@ is
(Local_Insert_Post,
Local_Insert_Sans_Hint);
- NN : Tree_Types.Nodes_Type renames Tree.Nodes;
+ NN : Tree_Types.Nodes_Type renames Tree.Content.Nodes;
--------------
-- New_Node --
@@ -1730,7 +1769,7 @@ is
return;
end if;
- Hint := Element_Keys.Ceiling (Tree, Item);
+ Hint := Element_Keys.Ceiling (Tree.Content, Item);
if Hint = 0 then
null;
@@ -1746,10 +1785,10 @@ is
raise Program_Error with "attempt to replace existing element";
end if;
- Tree_Operations.Delete_Node_Sans_Free (Tree, Node);
+ Tree_Operations.Delete_Node_Sans_Free (Tree.Content, Node);
Local_Insert_With_Hint
- (Tree => Tree,
+ (Tree => Tree.Content,
Position => Hint,
Key => Item,
Node => Result,
@@ -1770,7 +1809,7 @@ is
"Position cursor has no element";
end if;
- pragma Assert (Vet (Container, Position.Node),
+ pragma Assert (Vet (Container.Content, Position.Node),
"bad cursor in Replace_Element");
Replace_Element (Container, Position.Node, New_Item);
@@ -1830,7 +1869,7 @@ is
procedure Symmetric_Difference (Target : in out Set; Source : Set) is
begin
- Set_Ops.Set_Symmetric_Difference (Target, Source);
+ Set_Ops.Set_Symmetric_Difference (Target.Content, Source.Content);
end Symmetric_Difference;
function Symmetric_Difference (Left, Right : Set) return Set is
@@ -1840,15 +1879,17 @@ is
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
if Length (Left) = 0 then
- return Right.Copy;
+ return Copy (Right);
end if;
return S : Set (Length (Left) + Length (Right)) do
- Assign (S, Set_Ops.Set_Symmetric_Difference (Left, Right));
+ Assign
+ (S.Content,
+ Set_Ops.Set_Symmetric_Difference (Left.Content, Right.Content));
end return;
end Symmetric_Difference;
@@ -1861,7 +1902,7 @@ is
Inserted : Boolean;
begin
return S : Set (Capacity => 1) do
- Insert_Sans_Hint (S, New_Item, Node, Inserted);
+ Insert_Sans_Hint (S.Content, New_Item, Node, Inserted);
pragma Assert (Inserted);
end return;
end To_Set;
@@ -1872,21 +1913,21 @@ is
procedure Union (Target : in out Set; Source : Set) is
begin
- Set_Ops.Set_Union (Target, Source);
+ Set_Ops.Set_Union (Target.Content, Source.Content);
end Union;
function Union (Left, Right : Set) return Set is
begin
if Left'Address = Right'Address then
- return Left.Copy;
+ return Copy (Left);
end if;
if Length (Left) = 0 then
- return Right.Copy;
+ return Copy (Right);
end if;
if Length (Right) = 0 then
- return Left.Copy;
+ return Copy (Left);
end if;
return S : Set (Length (Left) + Length (Right)) do
diff --git a/gcc/ada/libgnat/a-cforse.ads b/gcc/ada/libgnat/a-cforse.ads
index 12d2d3c..e1d7c91 100644
--- a/gcc/ada/libgnat/a-cforse.ads
+++ b/gcc/ada/libgnat/a-cforse.ads
@@ -529,6 +529,16 @@ is
Position => Position)
and Positions (Container) = Positions (Container)'Old;
+ function Constant_Reference
+ (Container : aliased Set;
+ Position : Cursor) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Has_Element (Container, Position),
+ Post =>
+ Constant_Reference'Result.all =
+ E.Get (Elements (Container), P.Get (Positions (Container), Position));
+
procedure Move (Target : in out Set; Source : in out Set) with
Global => null,
Pre => Target.Capacity >= Length (Source),
@@ -1770,18 +1780,19 @@ private
type Node_Type is record
Has_Element : Boolean := False;
- Parent : Count_Type := 0;
- Left : Count_Type := 0;
- Right : Count_Type := 0;
- Color : Red_Black_Trees.Color_Type;
- Element : Element_Type;
+ Parent : Count_Type := 0;
+ Left : Count_Type := 0;
+ Right : Count_Type := 0;
+ Color : Red_Black_Trees.Color_Type;
+ Element : aliased Element_Type;
end record;
package Tree_Types is
new Red_Black_Trees.Generic_Bounded_Tree_Types (Node_Type);
- type Set (Capacity : Count_Type) is
- new Tree_Types.Tree_Type (Capacity) with null record;
+ type Set (Capacity : Count_Type) is record
+ Content : Tree_Types.Tree_Type (Capacity);
+ end record;
use Red_Black_Trees;
diff --git a/gcc/ada/libgnat/a-coboho.adb b/gcc/ada/libgnat/a-coboho.adb
index 32346d0..21b9f54 100644
--- a/gcc/ada/libgnat/a-coboho.adb
+++ b/gcc/ada/libgnat/a-coboho.adb
@@ -65,6 +65,26 @@ package body Ada.Containers.Bounded_Holders is
return Get (Left) = Get (Right);
end "=";
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Holder) return not null access constant Element_Type
+ is
+ begin
+ return Cast (Container'Address);
+ end Constant_Reference;
+
+ ---------
+ -- Get --
+ ---------
+
+ function Get (Container : Holder) return Element_Type is
+ begin
+ return Cast (Container'Address).all;
+ end Get;
+
---------------
-- Put_Image --
---------------
@@ -79,14 +99,16 @@ package body Ada.Containers.Bounded_Holders is
Array_After (S);
end Put_Image;
- ---------
- -- Get --
- ---------
+ ---------------
+ -- Reference --
+ ---------------
- function Get (Container : Holder) return Element_Type is
+ function Reference
+ (Container : not null access Holder) return not null access Element_Type
+ is
begin
- return Cast (Container'Address).all;
- end Get;
+ return Cast (Container.all'Address);
+ end Reference;
---------
-- Set --
diff --git a/gcc/ada/libgnat/a-coboho.ads b/gcc/ada/libgnat/a-coboho.ads
index 9dd73ba..086f194 100644
--- a/gcc/ada/libgnat/a-coboho.ads
+++ b/gcc/ada/libgnat/a-coboho.ads
@@ -81,6 +81,12 @@ package Ada.Containers.Bounded_Holders is
procedure Set (Container : in out Holder; New_Item : Element_Type);
+ function Constant_Reference
+ (Container : aliased Holder) return not null access constant Element_Type;
+
+ function Reference
+ (Container : not null access Holder) return not null access Element_Type;
+
private
-- The implementation uses low-level tricks (Address clauses and unchecked
diff --git a/gcc/ada/libgnat/a-cobove.adb b/gcc/ada/libgnat/a-cobove.adb
index f32afa1..e56cb94 100644
--- a/gcc/ada/libgnat/a-cobove.adb
+++ b/gcc/ada/libgnat/a-cobove.adb
@@ -415,7 +415,7 @@ package body Ada.Containers.Bounded_Vectors is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => A (J)'Access,
+ (Element => A (J)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -439,7 +439,7 @@ package body Ada.Containers.Bounded_Vectors is
Container.TC'Unrestricted_Access;
begin
return R : constant Constant_Reference_Type :=
- (Element => A (J)'Access,
+ (Element => A (J)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -2238,7 +2238,7 @@ package body Ada.Containers.Bounded_Vectors is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => A (J)'Access,
+ (Element => A (J)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
@@ -2262,7 +2262,7 @@ package body Ada.Containers.Bounded_Vectors is
Container.TC'Unrestricted_Access;
begin
return R : constant Reference_Type :=
- (Element => A (J)'Access,
+ (Element => A (J)'Unchecked_Access,
Control => (Controlled with TC))
do
Busy (TC.all);
diff --git a/gcc/ada/libgnat/a-cofove.adb b/gcc/ada/libgnat/a-cofove.adb
index a1f13ed..c7f4f06 100644
--- a/gcc/ada/libgnat/a-cofove.adb
+++ b/gcc/ada/libgnat/a-cofove.adb
@@ -142,6 +142,22 @@ is
Container.Last := No_Index;
end Clear;
+ ------------------------
+ -- Constant_Reference --
+ ------------------------
+
+ function Constant_Reference
+ (Container : aliased Vector;
+ Index : Index_Type) return not null access constant Element_Type
+ is
+ begin
+ if Index > Container.Last then
+ raise Constraint_Error with "Index is out of range";
+ end if;
+
+ return Container.Elements (To_Array_Index (Index))'Access;
+ end Constant_Reference;
+
--------------
-- Contains --
--------------
@@ -1096,6 +1112,22 @@ is
end;
end Replace_Element;
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference
+ (Container : not null access Vector;
+ Index : Index_Type) return not null access Element_Type
+ is
+ begin
+ if Index > Container.Last then
+ raise Constraint_Error with "Index is out of range";
+ end if;
+
+ return Container.Elements (To_Array_Index (Index))'Access;
+ end Reference;
+
----------------------
-- Reserve_Capacity --
----------------------
diff --git a/gcc/ada/libgnat/a-cofove.ads b/gcc/ada/libgnat/a-cofove.ads
index 61115dd..a4ed7e5 100644
--- a/gcc/ada/libgnat/a-cofove.ads
+++ b/gcc/ada/libgnat/a-cofove.ads
@@ -290,6 +290,48 @@ is
Right => Model (Container),
Position => Index);
+ function At_End (E : access constant Vector) return access constant Vector
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function At_End
+ (E : access constant Element_Type) return access constant Element_Type
+ is (E)
+ with Ghost,
+ Annotate => (GNATprove, At_End_Borrow);
+
+ function Constant_Reference
+ (Container : aliased Vector;
+ Index : Index_Type) return not null access constant Element_Type
+ with
+ Global => null,
+ Pre => Index in First_Index (Container) .. Last_Index (Container),
+ Post =>
+ Constant_Reference'Result.all = Element (Model (Container), Index);
+
+ function Reference
+ (Container : not null access Vector;
+ Index : Index_Type) return not null access Element_Type
+ with
+ Global => null,
+ Pre =>
+ Index in First_Index (Container.all) .. Last_Index (Container.all),
+ Post =>
+ Length (Container.all) = Length (At_End (Container).all)
+
+ -- Container will have Result.all at index Index
+
+ and At_End (Reference'Result).all =
+ Element (Model (At_End (Container).all), Index)
+
+ -- All other elements are preserved
+
+ and M.Equal_Except
+ (Left => Model (Container.all),
+ Right => Model (At_End (Container).all),
+ Position => Index);
+
procedure Insert
(Container : in out Vector;
Before : Extended_Index;
@@ -905,7 +947,7 @@ private
pragma Inline (Contains);
subtype Array_Index is Capacity_Range range 1 .. Capacity_Range'Last;
- type Elements_Array is array (Array_Index range <>) of Element_Type;
+ type Elements_Array is array (Array_Index range <>) of aliased Element_Type;
function "=" (L, R : Elements_Array) return Boolean is abstract;
type Vector (Capacity : Capacity_Range) is record
diff --git a/gcc/ada/libgnat/a-cofuma.ads b/gcc/ada/libgnat/a-cofuma.ads
index ca872e2..a1dd764 100644
--- a/gcc/ada/libgnat/a-cofuma.ads
+++ b/gcc/ada/libgnat/a-cofuma.ads
@@ -302,6 +302,14 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is
Global => null,
Pre => Has_Witness (Container, Witness);
+ function Copy_Key (Key : Key_Type) return Key_Type is (Key);
+ function Copy_Element (Item : Element_Type) return Element_Type is (Item);
+ -- Elements and Keys of maps are copied by numerous primitives in this
+ -- package. This function causes GNATprove to verify that such a copy is
+ -- valid (in particular, it does not break the ownership policy of SPARK,
+ -- i.e. it does not contain pointers that could be used to alias mutable
+ -- data).
+
---------------------------
-- Iteration Primitives --
---------------------------
diff --git a/gcc/ada/libgnat/a-cofuse.ads b/gcc/ada/libgnat/a-cofuse.ads
index d852be9..d0acba7 100644
--- a/gcc/ada/libgnat/a-cofuse.ads
+++ b/gcc/ada/libgnat/a-cofuse.ads
@@ -249,6 +249,13 @@ package Ada.Containers.Functional_Sets with SPARK_Mode is
and Right <= Union'Result
and Included_In_Union (Union'Result, Left, Right);
+ function Copy_Element (Item : Element_Type) return Element_Type is (Item);
+ -- Elements of containers are copied by numerous primitives in this
+ -- package. This function causes GNATprove to verify that such a copy is
+ -- valid (in particular, it does not break the ownership policy of SPARK,
+ -- i.e. it does not contain pointers that could be used to alias mutable
+ -- data).
+
---------------------------
-- Iteration Primitives --
---------------------------
diff --git a/gcc/ada/libgnat/a-cofuve.ads b/gcc/ada/libgnat/a-cofuve.ads
index bdd0e94..ee52730 100644
--- a/gcc/ada/libgnat/a-cofuve.ads
+++ b/gcc/ada/libgnat/a-cofuve.ads
@@ -336,6 +336,13 @@ package Ada.Containers.Functional_Vectors with SPARK_Mode is
Lst => Last (Remove'Result),
Offset => 1);
+ function Copy_Element (Item : Element_Type) return Element_Type is (Item);
+ -- Elements of containers are copied by numerous primitives in this
+ -- package. This function causes GNATprove to verify that such a copy is
+ -- valid (in particular, it does not break the ownership policy of SPARK,
+ -- i.e. it does not contain pointers that could be used to alias mutable
+ -- data).
+
---------------------------
-- Iteration Primitives --
---------------------------
diff --git a/gcc/ada/libgnat/a-cohama.adb b/gcc/ada/libgnat/a-cohama.adb
index 26bdd55..e6d6e4d 100644
--- a/gcc/ada/libgnat/a-cohama.adb
+++ b/gcc/ada/libgnat/a-cohama.adb
@@ -116,6 +116,13 @@ is
-- "=" --
---------
+ function "=" (Left, Right : Cursor) return Boolean is
+ begin
+ return
+ Left.Container = Right.Container
+ and then Left.Node = Right.Node;
+ end "=";
+
function "=" (Left, Right : Map) return Boolean is
begin
return Is_Equal (Left.HT, Right.HT);
@@ -636,7 +643,11 @@ is
end if;
Position.Container := Container'Unrestricted_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
+
+ -- Note that we do not set the Position component of the cursor,
+ -- because it may become incorrect on subsequent insertions/deletions
+ -- from the container. This will lose some optimizations but prevents
+ -- anomalies when the underlying hash-table is expanded or shrunk.
end Insert;
procedure Insert
@@ -679,7 +690,6 @@ is
end if;
Position.Container := Container'Unrestricted_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
end Insert;
procedure Insert
diff --git a/gcc/ada/libgnat/a-cohama.ads b/gcc/ada/libgnat/a-cohama.ads
index a04cb3a..3f172bd 100644
--- a/gcc/ada/libgnat/a-cohama.ads
+++ b/gcc/ada/libgnat/a-cohama.ads
@@ -110,6 +110,14 @@ is
type Cursor is private;
pragma Preelaborable_Initialization (Cursor);
+ function "=" (Left, Right : Cursor) return Boolean;
+ -- The representation of cursors includes a component used to optimize
+ -- iteration over maps. This component may become unreliable after
+ -- multiple map insertions, and must be excluded from cursor equality,
+ -- so we need to provide an explicit definition for it, instead of
+ -- using predefined equality (as implied by a questionable comment
+ -- in the RM).
+
Empty_Map : constant Map;
-- Map objects declared without an initialization expression are
-- initialized to the value Empty_Map.
diff --git a/gcc/ada/libgnat/a-cohase.adb b/gcc/ada/libgnat/a-cohase.adb
index 31374f6..2342116 100644
--- a/gcc/ada/libgnat/a-cohase.adb
+++ b/gcc/ada/libgnat/a-cohase.adb
@@ -145,6 +145,13 @@ is
-- "=" --
---------
+ function "=" (Left, Right : Cursor) return Boolean is
+ begin
+ return
+ Left.Container = Right.Container
+ and then Left.Node = Right.Node;
+ end "=";
+
function "=" (Left, Right : Set) return Boolean is
begin
return Is_Equal (Left.HT, Right.HT);
@@ -763,11 +770,14 @@ is
Position : out Cursor;
Inserted : out Boolean)
is
- HT : Hash_Table_Type renames Container'Unrestricted_Access.HT;
begin
Insert (Container.HT, New_Item, Position.Node, Inserted);
Position.Container := Container'Unchecked_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
+
+ -- Note that we do not set the Position component of the cursor,
+ -- because it may become incorrect on subsequent insertions/deletions
+ -- from the container. This will lose some optimizations but prevents
+ -- anomalies when the underlying hash-table is expanded or shrunk.
end Insert;
procedure Insert
diff --git a/gcc/ada/libgnat/a-cohase.ads b/gcc/ada/libgnat/a-cohase.ads
index f0763af..2356ba7 100644
--- a/gcc/ada/libgnat/a-cohase.ads
+++ b/gcc/ada/libgnat/a-cohase.ads
@@ -69,6 +69,15 @@ is
type Cursor is private;
pragma Preelaborable_Initialization (Cursor);
+ function "=" (Left, Right : Cursor) return Boolean;
+ -- The representation of cursors includes a component used to optimize
+ -- iteration over sets. This component may become unreliable after
+ -- multiple set insertions, and must be excluded from cursor equality,
+ -- so we need to provide an explicit definition for it, instead of
+ -- using predefined equality (as implied by a questionable comment
+ -- in the RM). This is also the case for hashed maps, and affects the
+ -- use of Insert primitives in hashed structures.
+
Empty_Set : constant Set;
-- Set objects declared without an initialization expression are
-- initialized to the value Empty_Set.
diff --git a/gcc/ada/libgnat/a-conhel.adb b/gcc/ada/libgnat/a-conhel.adb
index e7d82ac..316c866 100644
--- a/gcc/ada/libgnat/a-conhel.adb
+++ b/gcc/ada/libgnat/a-conhel.adb
@@ -27,6 +27,13 @@
package body Ada.Containers.Helpers is
+ Max_Count : constant := 2**31 - 1;
+ -- Used in assertions below, to make sure the counts don't wrap around.
+ -- This can help detect bugs in which Adjust and Finalize calls are
+ -- improperly generated. An extra Decrement could otherwise cause
+ -- wraparound from 0 to 2**32-1. The highest count seen so far is
+ -- around 25, so this should be plenty.
+
package body Generic_Implementation is
use type SAC.Atomic_Unsigned;
@@ -50,6 +57,7 @@ package body Ada.Containers.Helpers is
begin
if T_Check then
SAC.Increment (T_Counts.Busy);
+ pragma Assert (T_Counts.Busy <= Max_Count);
end if;
end Busy;
@@ -112,7 +120,9 @@ package body Ada.Containers.Helpers is
begin
if T_Check then
SAC.Increment (T_Counts.Lock);
+ pragma Assert (T_Counts.Lock <= Max_Count);
SAC.Increment (T_Counts.Busy);
+ pragma Assert (T_Counts.Busy <= Max_Count);
end if;
end Lock;
@@ -158,6 +168,7 @@ package body Ada.Containers.Helpers is
begin
if T_Check then
SAC.Decrement (T_Counts.Busy);
+ pragma Assert (T_Counts.Busy <= Max_Count);
end if;
end Unbusy;
@@ -169,7 +180,9 @@ package body Ada.Containers.Helpers is
begin
if T_Check then
SAC.Decrement (T_Counts.Lock);
+ pragma Assert (T_Counts.Lock <= Max_Count);
SAC.Decrement (T_Counts.Busy);
+ pragma Assert (T_Counts.Busy <= Max_Count);
end if;
end Unlock;
diff --git a/gcc/ada/libgnat/a-ngelfu.ads b/gcc/ada/libgnat/a-ngelfu.ads
index 055c282..523e64f 100644
--- a/gcc/ada/libgnat/a-ngelfu.ads
+++ b/gcc/ada/libgnat/a-ngelfu.ads
@@ -126,7 +126,7 @@ is
Pre => Cycle > 0.0
and then X /= 0.0
and then Float_Type'Base'Remainder (X, Cycle) /= 0.0
- and then abs Float_Type'Base'Remainder (X, Cycle) = 0.5 * Cycle;
+ and then abs Float_Type'Base'Remainder (X, Cycle) /= 0.5 * Cycle;
function Arcsin (X : Float_Type'Base) return Float_Type'Base with
Pre => abs X <= 1.0,
diff --git a/gcc/ada/libgnat/a-stobbu.adb b/gcc/ada/libgnat/a-stobbu.adb
deleted file mode 100644
index 560fab2..0000000
--- a/gcc/ada/libgnat/a-stobbu.adb
+++ /dev/null
@@ -1,53 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BIT_BUCKETS --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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 Ada.Strings.Text_Output.Bit_Buckets is
-
- type Bit_Bucket_Type is new Sink with null record;
- overriding procedure Full_Method (S : in out Bit_Bucket_Type);
- overriding procedure Flush_Method (S : in out Bit_Bucket_Type);
-
- The_Bit_Bucket : aliased Bit_Bucket_Type
- (Chunk_Length => Default_Chunk_Length);
- function Bit_Bucket return Sink_Access is (The_Bit_Bucket'Access);
-
- overriding procedure Full_Method (S : in out Bit_Bucket_Type)
- renames Flush_Method;
-
- overriding procedure Flush_Method (S : in out Bit_Bucket_Type) is
- begin
- S.Last := 0;
- end Flush_Method;
-
-begin
- The_Bit_Bucket.Indent_Amount := 0;
- The_Bit_Bucket.Cur_Chunk := The_Bit_Bucket.Initial_Chunk'Access;
-end Ada.Strings.Text_Output.Bit_Buckets;
diff --git a/gcc/ada/libgnat/a-stobbu.ads b/gcc/ada/libgnat/a-stobbu.ads
deleted file mode 100644
index b8710d0..0000000
--- a/gcc/ada/libgnat/a-stobbu.ads
+++ /dev/null
@@ -1,34 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BIT_BUCKETS --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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 Ada.Strings.Text_Output.Bit_Buckets is
- function Bit_Bucket return Sink_Access;
-end Ada.Strings.Text_Output.Bit_Buckets;
diff --git a/gcc/ada/libgnat/a-stobfi.adb b/gcc/ada/libgnat/a-stobfi.adb
deleted file mode 100644
index 942f151..0000000
--- a/gcc/ada/libgnat/a-stobfi.adb
+++ /dev/null
@@ -1,118 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BASIC_FILES --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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.Strings.Text_Output.Utils; use Ada.Strings.Text_Output.Utils;
-package body Ada.Strings.Text_Output.Basic_Files is
- use type OS.File_Descriptor;
-
- function Create_From_FD
- (FD : OS.File_Descriptor;
- Indent_Amount : Natural;
- Chunk_Length : Positive) return File;
- -- Create a file from an OS file descriptor
-
- function Create_From_FD
- (FD : OS.File_Descriptor;
- Indent_Amount : Natural;
- Chunk_Length : Positive) return File
- is
- begin
- if FD = OS.Invalid_FD then
- raise Program_Error with OS.Errno_Message;
- end if;
- return Result : File (Chunk_Length) do
- Result.Indent_Amount := Indent_Amount;
- Result.Cur_Chunk := Result.Initial_Chunk'Unchecked_Access;
- Result.FD := FD;
- end return;
- end Create_From_FD;
-
- function Create_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File
- is
- begin
- return Create_From_FD
- (OS.Create_File (Name, Fmode => OS.Binary),
- Indent_Amount, Chunk_Length);
- end Create_File;
-
- function Create_New_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File
- is
- begin
- return Create_From_FD
- (OS.Create_New_File (Name, Fmode => OS.Binary),
- Indent_Amount, Chunk_Length);
- end Create_New_File;
-
- procedure Close (S : in out File'Class) is
- Status : Boolean;
- begin
- Flush (S);
-
- if S.FD not in OS.Standout | OS.Standerr then -- Don't close these
- OS.Close (S.FD, Status);
- if not Status then
- raise Program_Error with OS.Errno_Message;
- end if;
- end if;
- end Close;
-
- overriding procedure Full_Method (S : in out File) renames Flush_Method;
-
- overriding procedure Flush_Method (S : in out File) is
- pragma Assert (S.Cur_Chunk = S.Initial_Chunk'Unchecked_Access);
- Res : constant Integer :=
- OS.Write (S.FD, S.Cur_Chunk.Chars'Address, S.Last);
- begin
- if Res /= S.Last then
- raise Program_Error with OS.Errno_Message;
- end if;
- S.Last := 0;
- end Flush_Method;
-
- The_Stdout : aliased File :=
- Create_From_FD (OS.Standout,
- Indent_Amount => Default_Indent_Amount,
- Chunk_Length => Default_Chunk_Length);
- The_Stderr : aliased File :=
- Create_From_FD (OS.Standerr,
- Indent_Amount => Default_Indent_Amount,
- Chunk_Length => Default_Chunk_Length);
-
- function Standard_Output return Sink_Access is (The_Stdout'Access);
- function Standard_Error return Sink_Access is (The_Stderr'Access);
-
-end Ada.Strings.Text_Output.Basic_Files;
diff --git a/gcc/ada/libgnat/a-stobfi.ads b/gcc/ada/libgnat/a-stobfi.ads
deleted file mode 100644
index 89fcb4d..0000000
--- a/gcc/ada/libgnat/a-stobfi.ads
+++ /dev/null
@@ -1,66 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BASIC_FILES --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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. --
--- --
-------------------------------------------------------------------------------
-
-private with GNAT.OS_Lib;
-package Ada.Strings.Text_Output.Basic_Files is
- -- Normally, you should use Ada.Strings.Text_Output.Files, which
- -- automatically Closes files via finalization. If you don't want to use
- -- finalization, use this package instead. You must then Close the file by
- -- hand. The semantics is otherwise the same as Files.
-
- function Standard_Output return Sink_Access;
- function Standard_Error return Sink_Access;
-
- type File (<>) is new Sink with private;
-
- function Create_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File;
- function Create_New_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File;
-
- procedure Close (S : in out File'Class);
-
-private
-
- package OS renames GNAT.OS_Lib;
-
- type File is new Sink with record
- FD : OS.File_Descriptor := OS.Invalid_FD;
- end record;
-
- overriding procedure Full_Method (S : in out File);
- overriding procedure Flush_Method (S : in out File);
-
-end Ada.Strings.Text_Output.Basic_Files;
diff --git a/gcc/ada/libgnat/a-stoubu.adb b/gcc/ada/libgnat/a-stoubu.adb
deleted file mode 100644
index 3c54338..0000000
--- a/gcc/ada/libgnat/a-stoubu.adb
+++ /dev/null
@@ -1,148 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BUFFERS --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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 Unchecked_Deallocation;
-with Ada.Strings.UTF_Encoding.Strings;
-with Ada.Strings.UTF_Encoding.Wide_Strings;
-with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
-package body Ada.Strings.Text_Output.Buffers is
-
- type Chunk_Access is access all Chunk;
-
- function New_Buffer
- (Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return Buffer
- is
- begin
- return Result : Buffer (Chunk_Length) do
- Result.Indent_Amount := Indent_Amount;
- Result.Cur_Chunk := Result.Initial_Chunk'Unchecked_Access;
- end return;
- end New_Buffer;
-
- -- We need type conversions of Chunk_Access values in the following two
- -- procedures, because the one in Text_Output has Storage_Size => 0,
- -- because Text_Output is Pure. We do not run afoul of 13.11.2(16/3),
- -- which requires the allocation and deallocation to have the same pool,
- -- because the allocation in Full_Method and the deallocation in Destroy
- -- use the same access type, and therefore the same pool.
-
- procedure Destroy (S : in out Buffer) is
- procedure Free is new Unchecked_Deallocation (Chunk, Chunk_Access);
- Cur : Chunk_Access := Chunk_Access (S.Initial_Chunk.Next);
- begin
- while Cur /= null loop
- declare
- Temp : constant Chunk_Access := Chunk_Access (Cur.Next);
- begin
- Free (Cur);
- Cur := Temp;
- end;
- end loop;
-
- S.Cur_Chunk := null;
- end Destroy;
-
- overriding procedure Full_Method (S : in out Buffer) is
- begin
- pragma Assert (S.Cur_Chunk.Next = null);
- pragma Assert (S.Last = S.Cur_Chunk.Chars'Length);
- S.Cur_Chunk.Next :=
- Text_Output.Chunk_Access (Chunk_Access'(new Chunk (S.Chunk_Length)));
- S.Cur_Chunk := S.Cur_Chunk.Next;
- S.Num_Extra_Chunks := S.Num_Extra_Chunks + 1;
- S.Last := 0;
- end Full_Method;
-
- function UTF_8_Length (S : Buffer'Class) return Natural is
- begin
- return S.Num_Extra_Chunks * S.Chunk_Length + S.Last;
- end UTF_8_Length;
-
- procedure Get_UTF_8
- (S : Buffer'Class; Result : out UTF_8_Lines)
- is
- Cur : access constant Chunk := S.Initial_Chunk'Access;
- First : Positive := 1;
- begin
- loop
- if Cur.Next = null then
- pragma Assert (Result'Last = First + S.Last - 1);
- Result (First .. Result'Last) := Cur.Chars (1 .. S.Last);
- exit;
- end if;
-
- pragma Assert (S.Chunk_Length = Cur.Chars'Length);
- Result (First .. First + S.Chunk_Length - 1) := Cur.Chars;
- First := First + S.Chunk_Length;
- Cur := Cur.Next;
- end loop;
- end Get_UTF_8;
-
- function Get_UTF_8 (S : Buffer'Class) return UTF_8_Lines is
- begin
- return Result : String (1 .. UTF_8_Length (S)) do
- Get_UTF_8 (S, Result);
- end return;
- end Get_UTF_8;
-
- function Get (S : Buffer'Class) return String is
- begin
- -- If all characters are 7 bits, we don't need to decode;
- -- this is an optimization.
-
- -- Otherwise, if all are 8 bits, we need to decode to get Latin-1.
- -- Otherwise, the result is implementation defined, so we return a
- -- String encoded as UTF-8. (Note that the AI says "if any character
- -- in the sequence is not defined in Character, the result is
- -- implementation-defined", so we are not obliged to decode ANY
- -- Latin-1 characters if ANY character is bigger than 8 bits.
-
- if S.All_7_Bits then
- return Get_UTF_8 (S);
- elsif S.All_8_Bits then
- return UTF_Encoding.Strings.Decode (Get_UTF_8 (S));
- else
- return Get_UTF_8 (S);
- end if;
- end Get;
-
- function Wide_Get (S : Buffer'Class) return Wide_String is
- begin
- return UTF_Encoding.Wide_Strings.Decode (Get_UTF_8 (S));
- end Wide_Get;
-
- function Wide_Wide_Get (S : Buffer'Class) return Wide_Wide_String is
- begin
- return UTF_Encoding.Wide_Wide_Strings.Decode (Get_UTF_8 (S));
- end Wide_Wide_Get;
-
-end Ada.Strings.Text_Output.Buffers;
diff --git a/gcc/ada/libgnat/a-stoubu.ads b/gcc/ada/libgnat/a-stoubu.ads
deleted file mode 100644
index 0370cae..0000000
--- a/gcc/ada/libgnat/a-stoubu.ads
+++ /dev/null
@@ -1,73 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.BUFFERS --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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 Ada.Strings.Text_Output.Buffers is
-
- type Buffer (<>) is new Sink with private;
-
- function New_Buffer
- (Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return Buffer;
-
- procedure Destroy (S : in out Buffer);
- -- Reclaim any heap-allocated data, and render the Buffer unusable.
- -- It would make sense to do this via finalization, but we wish to
- -- avoid controlled types in the generated code for 'Image.
-
- function Get_UTF_8 (S : Buffer'Class) return UTF_8_Lines;
- -- Get the characters in S, encoded as UTF-8.
-
- function UTF_8_Length (S : Buffer'Class) return Natural;
- procedure Get_UTF_8
- (S : Buffer'Class; Result : out UTF_8_Lines) with
- Pre => Result'First = 1 and Result'Last = UTF_8_Length (S);
- -- This is a procedure version of the Get_UTF_8 function, for
- -- efficiency. The Result String must be the exact right length.
-
- function Get (S : Buffer'Class) return String;
- function Wide_Get (S : Buffer'Class) return Wide_String;
- function Wide_Wide_Get (S : Buffer'Class) return Wide_Wide_String;
- -- Get the characters in S, decoded as [[Wide_]Wide_]String.
- -- There is no need for procedure versions of these, because
- -- they are intended primarily to implement the [[Wide_]Wide_]Image
- -- attribute, which is already a function.
-
-private
- type Chunk_Count is new Natural;
- type Buffer is new Sink with record
- Num_Extra_Chunks : Natural := 0;
- -- Number of chunks in the linked list, not including Initial_Chunk.
- end record;
-
- overriding procedure Full_Method (S : in out Buffer);
- overriding procedure Flush_Method (S : in out Buffer) is null;
-
-end Ada.Strings.Text_Output.Buffers;
diff --git a/gcc/ada/libgnat/a-stoufi.adb b/gcc/ada/libgnat/a-stoufi.adb
deleted file mode 100644
index 3444e3b..0000000
--- a/gcc/ada/libgnat/a-stoufi.adb
+++ /dev/null
@@ -1,123 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.FILES --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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.Strings.Text_Output.Utils; use Ada.Strings.Text_Output.Utils;
-package body Ada.Strings.Text_Output.Files is
- use type OS.File_Descriptor;
-
- function Create_From_FD
- (FD : OS.File_Descriptor;
- Indent_Amount : Natural;
- Chunk_Length : Positive) return File;
- -- Create a file from an OS file descriptor
-
- function Create_From_FD
- (FD : OS.File_Descriptor;
- Indent_Amount : Natural;
- Chunk_Length : Positive) return File
- is
- begin
- if FD = OS.Invalid_FD then
- raise Program_Error;
- end if;
- return Result : File (Chunk_Length) do
- Result.Indent_Amount := Indent_Amount;
- Result.Cur_Chunk := Result.Initial_Chunk'Unchecked_Access;
- Result.FD := FD;
- end return;
- end Create_From_FD;
-
- function Create_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File
- is
- begin
- return Create_From_FD
- (OS.Create_File (Name, Fmode => OS.Binary),
- Indent_Amount, Chunk_Length);
- end Create_File;
-
- function Create_New_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File
- is
- begin
- return Create_From_FD
- (OS.Create_New_File (Name, Fmode => OS.Binary),
- Indent_Amount, Chunk_Length);
- end Create_New_File;
-
- overriding procedure Finalize (Ref : in out Self_Ref) is
- begin
- Close (Ref.Self.all);
- end Finalize;
-
- procedure Close (S : in out File'Class) is
- Status : Boolean;
- begin
- Flush (S);
-
- if S.FD not in OS.Standout | OS.Standerr then -- Don't close these
- OS.Close (S.FD, Status);
- if not Status then
- raise Program_Error;
- end if;
- end if;
- end Close;
-
- overriding procedure Full_Method (S : in out File) renames Flush_Method;
-
- overriding procedure Flush_Method (S : in out File) is
- pragma Assert (S.Cur_Chunk = S.Initial_Chunk'Unchecked_Access);
- Res : constant Integer :=
- OS.Write (S.FD, S.Cur_Chunk.Chars'Address, S.Last);
- begin
- if Res /= S.Last then
- raise Program_Error;
- end if;
- S.Last := 0;
- end Flush_Method;
-
- The_Stdout : aliased File :=
- Create_From_FD (OS.Standout,
- Indent_Amount => Default_Indent_Amount,
- Chunk_Length => Default_Chunk_Length);
- The_Stderr : aliased File :=
- Create_From_FD (OS.Standerr,
- Indent_Amount => Default_Indent_Amount,
- Chunk_Length => Default_Chunk_Length);
-
- function Standard_Output return Sink_Access is (The_Stdout'Access);
- function Standard_Error return Sink_Access is (The_Stderr'Access);
-
-end Ada.Strings.Text_Output.Files;
diff --git a/gcc/ada/libgnat/a-stoufi.ads b/gcc/ada/libgnat/a-stoufi.ads
deleted file mode 100644
index 330b84f..0000000
--- a/gcc/ada/libgnat/a-stoufi.ads
+++ /dev/null
@@ -1,72 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.FILES --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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. --
--- --
-------------------------------------------------------------------------------
-
-private with GNAT.OS_Lib;
-private with Ada.Finalization;
-package Ada.Strings.Text_Output.Files is
- -- This package supports a Sink type that sends output to a file. The file
- -- is automatically closed when finalized.
-
- function Standard_Output return Sink_Access;
- function Standard_Error return Sink_Access;
-
- type File (<>) is new Sink with private;
-
- function Create_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File;
- function Create_New_File
- (Name : String;
- Indent_Amount : Natural := Default_Indent_Amount;
- Chunk_Length : Positive := Default_Chunk_Length) return File;
- -- Create a file. Create_New_File raises an exception if the file already
- -- exists; Create_File overwrites.
-
- procedure Close (S : in out File'Class);
-
-private
-
- package OS renames GNAT.OS_Lib;
-
- type Self_Ref (Self : access File) is new Finalization.Limited_Controlled
- with null record;
- overriding procedure Finalize (Ref : in out Self_Ref);
-
- type File is new Sink with record
- FD : OS.File_Descriptor := OS.Invalid_FD;
- Ref : Self_Ref (File'Access);
- end record;
-
- overriding procedure Full_Method (S : in out File);
- overriding procedure Flush_Method (S : in out File);
-
-end Ada.Strings.Text_Output.Files;
diff --git a/gcc/ada/libgnat/a-stoufo.adb b/gcc/ada/libgnat/a-stoufo.adb
deleted file mode 100644
index 3be8826..0000000
--- a/gcc/ada/libgnat/a-stoufo.adb
+++ /dev/null
@@ -1,155 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.FORMATTING --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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.Strings.Text_Output.Files;
-with Ada.Strings.Text_Output.Buffers; use Ada.Strings.Text_Output.Buffers;
-with Ada.Strings.Text_Output.Utils; use Ada.Strings.Text_Output.Utils;
-package body Ada.Strings.Text_Output.Formatting is
-
- procedure Put
- (S : in out Sink'Class; T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
- is
- J : Positive := T'First;
- Used : array (1 .. 9) of Boolean := (others => False);
- begin
- while J <= T'Last loop
- if T (J) = '\' then
- J := J + 1;
- case T (J) is
- when 'n' =>
- New_Line (S);
- when '\' =>
- Put_7bit (S, '\');
- when 'i' =>
- Indent (S);
- when 'o' =>
- Outdent (S);
- when 'I' =>
- Indent (S, 1);
- when 'O' =>
- Outdent (S, 1);
-
- when '1' =>
- Used (1) := True;
- Put_UTF_8_Lines (S, X1);
- when '2' =>
- Used (2) := True;
- Put_UTF_8_Lines (S, X2);
- when '3' =>
- Used (3) := True;
- Put_UTF_8_Lines (S, X3);
- when '4' =>
- Used (4) := True;
- Put_UTF_8_Lines (S, X4);
- when '5' =>
- Used (5) := True;
- Put_UTF_8_Lines (S, X5);
- when '6' =>
- Used (6) := True;
- Put_UTF_8_Lines (S, X6);
- when '7' =>
- Used (7) := True;
- Put_UTF_8_Lines (S, X7);
- when '8' =>
- Used (8) := True;
- Put_UTF_8_Lines (S, X8);
- when '9' =>
- Used (9) := True;
- Put_UTF_8_Lines (S, X9);
-
- when others =>
- raise Program_Error;
- end case;
- else
- Put_7bit (S, T (J));
- end if;
-
- J := J + 1;
- end loop;
-
- if not Used (1) then
- pragma Assert (X1 = "");
- end if;
- if not Used (2) then
- pragma Assert (X2 = "");
- end if;
- if not Used (3) then
- pragma Assert (X3 = "");
- end if;
- if not Used (4) then
- pragma Assert (X4 = "");
- end if;
- if not Used (5) then
- pragma Assert (X5 = "");
- end if;
- if not Used (6) then
- pragma Assert (X6 = "");
- end if;
- if not Used (7) then
- pragma Assert (X7 = "");
- end if;
- if not Used (8) then
- pragma Assert (X8 = "");
- end if;
- if not Used (9) then
- pragma Assert (X9 = "");
- end if;
-
- Flush (S);
- end Put;
-
- procedure Put
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "") is
- begin
- Put (Files.Standard_Output.all, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
- end Put;
-
- procedure Err
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "") is
- begin
- Put (Files.Standard_Error.all, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
- end Err;
-
- function Format
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
- return UTF_8_Lines
- is
- Buf : Buffer := New_Buffer;
- begin
- Put (Buf, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
- return Get_UTF_8 (Buf);
- end Format;
-
-end Ada.Strings.Text_Output.Formatting;
diff --git a/gcc/ada/libgnat/a-stoufo.ads b/gcc/ada/libgnat/a-stoufo.ads
deleted file mode 100644
index a03d087..0000000
--- a/gcc/ada/libgnat/a-stoufo.ads
+++ /dev/null
@@ -1,72 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.FORMATTING --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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 Ada.Strings.Text_Output.Formatting is
-
- -- Template-based output, based loosely on C's printf family. Unlike
- -- printf, it is type safe. We don't support myriad formatting options; the
- -- caller is expected to call 'Image, or other functions that might have
- -- various formatting capabilities.
- --
- -- Each of the following calls Flush
-
- type Template is new UTF_8;
- procedure Put
- (S : in out Sink'Class; T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
- -- Prints the template as is, except for the following escape sequences:
- -- "\n" is end of line.
- -- "\i" indents by the default amount, and "\o" outdents.
- -- "\I" indents by one space, and "\O" outdents.
- -- "\1" is replaced with X1, and similarly for 2, 3, ....
- -- "\\" is "\".
-
- -- Note that the template is not type String, to avoid this sort of thing:
- --
- -- https://xkcd.com/327/
-
- procedure Put
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
- -- Sends to standard output
-
- procedure Err
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
- -- Sends to standard error
-
- function Format
- (T : Template;
- X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
- return UTF_8_Lines;
- -- Returns a UTF-8-encoded String
-
-end Ada.Strings.Text_Output.Formatting;
diff --git a/gcc/ada/libgnat/a-stouut.adb b/gcc/ada/libgnat/a-stouut.adb
deleted file mode 100644
index 6b8f72b..0000000
--- a/gcc/ada/libgnat/a-stouut.adb
+++ /dev/null
@@ -1,272 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.UTILS --
--- --
--- B o d y --
--- --
--- Copyright (C) 2020-2021, 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.Strings.UTF_Encoding.Wide_Wide_Strings;
-
-package body Ada.Strings.Text_Output.Utils is
-
- procedure Put_Octet (S : in out Sink'Class; Item : Character) with Inline;
- -- Send a single octet to the current Chunk
-
- procedure Adjust_Column (S : in out Sink'Class) with Inline;
- -- Adjust the column for a non-NL character.
-
- procedure Put_UTF_8_Outline (S : in out Sink'Class; Item : UTF_8);
- -- Out-of-line portion of Put_UTF_8. This exists solely to make Put_UTF_8
- -- small enough to reasonably inline it.
-
- procedure Full (S : in out Sink'Class) is
- begin
- pragma Assert (S.Last = S.Chunk_Length);
- Full_Method (S);
- pragma Assert (S.Last = 0);
- end Full;
-
- procedure Flush (S : in out Sink'Class) is
- begin
- Flush_Method (S);
- end Flush;
-
- procedure Put_Octet (S : in out Sink'Class; Item : Character) is
- begin
- S.Last := S.Last + 1;
- S.Cur_Chunk.Chars (S.Last) := Item;
- pragma Assert (S.Chunk_Length = S.Cur_Chunk.Chars'Length);
- if S.Last = S.Chunk_Length then
- Full (S);
- end if;
- end Put_Octet;
-
- procedure Adjust_Column (S : in out Sink'Class) is
- begin
- -- If we're in the first column, indent. This is handled here, rather
- -- than when we see NL, because we don't want spaces in a blank line.
- -- The character we're about to put is not NL; NL is handled in
- -- New_Line. So after indenting, we simply increment the Column.
-
- if S.Column = 1 then
- Tab_To_Column (S, S.Indentation + 1);
- end if;
- S.Column := S.Column + 1;
- end Adjust_Column;
-
- procedure Put_7bit (S : in out Sink'Class; Item : Character_7) is
- begin
- Adjust_Column (S);
- Put_Octet (S, Item);
- end Put_7bit;
-
- procedure Put_7bit_NL (S : in out Sink'Class; Item : Character_7) is
- begin
- if Item = NL then
- New_Line (S);
- else
- Put_7bit (S, Item);
- end if;
- end Put_7bit_NL;
-
- procedure Put_Character (S : in out Sink'Class; Item : Character) is
- begin
- if Character'Pos (Item) < 2**7 then
- Put_7bit_NL (S, Item);
- else
- Put_Wide_Wide_Character (S, To_Wide_Wide (Item));
- end if;
- end Put_Character;
-
- procedure Put_Wide_Character
- (S : in out Sink'Class; Item : Wide_Character) is
- begin
- if Wide_Character'Pos (Item) < 2**7 then
- Put_7bit_NL (S, From_Wide (Item));
- else
- Put_Wide_Wide_Character (S, To_Wide_Wide (Item));
- end if;
- end Put_Wide_Character;
-
- procedure Put_Wide_Wide_Character
- (S : in out Sink'Class; Item : Wide_Wide_Character) is
- begin
- if Wide_Wide_Character'Pos (Item) < 2**7 then
- Put_7bit_NL (S, From_Wide_Wide (Item));
- else
- S.All_7_Bits := False;
- if Wide_Wide_Character'Pos (Item) >= 2**8 then
- S.All_8_Bits := False;
- end if;
- declare
- Temp : constant UTF_8_Lines :=
- UTF_Encoding.Wide_Wide_Strings.Encode ((1 => Item));
- begin
- for X of Temp loop
- pragma Assert (X /= NL);
- Adjust_Column (S);
- Put_Octet (S, X);
- end loop;
- end;
- end if;
- end Put_Wide_Wide_Character;
-
- procedure Put_UTF_8_Outline (S : in out Sink'Class; Item : UTF_8) is
- begin
- if S.Last + Item'Length = S.Chunk_Length then
- -- Item fits exactly in current chunk
-
- S.Cur_Chunk.Chars (S.Last + 1 .. S.Last + Item'Length) := Item;
- S.Last := S.Last + Item'Length;
- S.Column := S.Column + Item'Length;
- Full (S);
- -- ???Seems like maybe we shouldn't call Full until we have MORE
- -- characters. But then we can't pass Chunk_Length => 1 to
- -- Create_File to get unbuffered output.
- else
- -- We get here only if Item doesn't fit in the current chunk, which
- -- should be fairly rare. We split Item into Left and Right, where
- -- Left exactly fills the current chunk, and recurse on Left and
- -- Right. Right will fit into the next chunk unless it's very long,
- -- so another level of recursion will be extremely rare.
-
- declare
- Left_Length : constant Natural := S.Chunk_Length - S.Last;
- Right_First : constant Natural := Item'First + Left_Length;
- Left : UTF_8 renames Item (Item'First .. Right_First - 1);
- Right : UTF_8 renames Item (Right_First .. Item'Last);
- pragma Assert (Left & Right = Item);
- begin
- Put_UTF_8 (S, Left); -- This will call Full.
- Put_UTF_8 (S, Right); -- This might call Full, but probably not.
- end;
- end if;
- end Put_UTF_8_Outline;
-
- procedure Put_UTF_8 (S : in out Sink'Class; Item : UTF_8) is
- begin
- Adjust_Column (S);
-
- if S.Last + Item'Length < S.Chunk_Length then
- -- Item fits in current chunk
-
- S.Cur_Chunk.Chars (S.Last + 1 .. S.Last + Item'Length) := Item;
- S.Last := S.Last + Item'Length;
- S.Column := S.Column + Item'Length;
- else
- Put_UTF_8_Outline (S, Item);
- end if;
- end Put_UTF_8;
-
- procedure Put_UTF_8_Lines (S : in out Sink'Class; Item : UTF_8_Lines) is
- Line_Start, Index : Integer := Item'First;
- -- Needs to be Integer, because Item'First might be negative for empty
- -- Items.
- begin
- while Index <= Item'Last loop
- if Item (Index) = NL then
- if Index > Line_Start then
- Put_UTF_8 (S, Item (Line_Start .. Index - 1));
- end if;
- New_Line (S);
- Line_Start := Index + 1;
- end if;
-
- Index := Index + 1;
- end loop;
-
- if Index > Line_Start then
- Put_UTF_8 (S, Item (Line_Start .. Index - 1));
- end if;
- end Put_UTF_8_Lines;
-
- procedure Put_String (S : in out Sink'Class; Item : String) is
- begin
- for X of Item loop
- Put_Character (S, X);
- end loop;
- end Put_String;
-
- procedure Put_Wide_String (S : in out Sink'Class; Item : Wide_String) is
- begin
- for X of Item loop
- Put_Wide_Character (S, X);
- end loop;
- end Put_Wide_String;
-
- procedure Put_Wide_Wide_String
- (S : in out Sink'Class; Item : Wide_Wide_String) is
- begin
- for X of Item loop
- Put_Wide_Wide_Character (S, X);
- end loop;
- end Put_Wide_Wide_String;
-
- procedure New_Line (S : in out Sink'Class) is
- begin
- S.Column := 1;
- Put_Octet (S, NL);
- end New_Line;
-
- function Column (S : Sink'Class) return Positive is (S.Column);
-
- procedure Tab_To_Column (S : in out Sink'Class; Column : Positive) is
- begin
- if S.Column < Column then
- for X in 1 .. Column - S.Column loop
- Put_Octet (S, ' ');
- end loop;
- S.Column := Column;
- end if;
- end Tab_To_Column;
-
- procedure Set_Indentation (S : in out Sink'Class; Amount : Natural) is
- begin
- S.Indentation := Amount;
- end Set_Indentation;
-
- function Indentation (S : Sink'Class) return Natural is (S.Indentation);
-
- procedure Indent
- (S : in out Sink'Class; Amount : Optional_Indentation := Default)
- is
- By : constant Natural :=
- (if Amount = Default then S.Indent_Amount else Amount);
- begin
- Set_Indentation (S, Indentation (S) + By);
- end Indent;
-
- procedure Outdent
- (S : in out Sink'Class; Amount : Optional_Indentation := Default)
- is
- By : constant Natural :=
- (if Amount = Default then S.Indent_Amount else Amount);
- begin
- Set_Indentation (S, Indentation (S) - By);
- end Outdent;
-
-end Ada.Strings.Text_Output.Utils;
diff --git a/gcc/ada/libgnat/a-stouut.ads b/gcc/ada/libgnat/a-stouut.ads
deleted file mode 100644
index 69cde55..0000000
--- a/gcc/ada/libgnat/a-stouut.ads
+++ /dev/null
@@ -1,107 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT.UTILS --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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 Ada.Strings.Text_Output.Utils with Pure is
-
- -- This package provides utility functions on Sink'Class. These are
- -- intended for use by Put_Image attributes, both the default versions
- -- generated by the compiler, and user-defined ones.
-
- procedure Full (S : in out Sink'Class) with Inline;
- -- Must be called when the current chunk is full. Dispatches to
- -- Full_Method.
-
- procedure Flush (S : in out Sink'Class) with Inline;
- -- Dispatches to Flush_Method
-
- -- Full_Method and Flush_Method should be called only via Full and Flush
-
- procedure Put_Character (S : in out Sink'Class; Item : Character);
- procedure Put_Wide_Character (S : in out Sink'Class; Item : Wide_Character);
- procedure Put_Wide_Wide_Character
- (S : in out Sink'Class; Item : Wide_Wide_Character);
- procedure Put_String (S : in out Sink'Class; Item : String);
- procedure Put_Wide_String (S : in out Sink'Class; Item : Wide_String);
- procedure Put_Wide_Wide_String
- (S : in out Sink'Class; Item : Wide_Wide_String);
- -- Encode characters or strings as UTF-8, and send them to S.
-
- subtype Character_7 is
- Character range Character'Val (0) .. Character'Val (2**7 - 1);
- -- 7-bit character. These are the same in both Latin-1 and UTF-8.
-
- procedure Put_7bit (S : in out Sink'Class; Item : Character_7)
- with Inline, Pre => Item /= NL;
- procedure Put_7bit_NL (S : in out Sink'Class; Item : Character_7)
- with Inline;
- -- Put a 7-bit character, and adjust the Column. For Put_7bit_NL, Item can
- -- be NL.
-
- procedure Put_UTF_8 (S : in out Sink'Class; Item : UTF_8) with Inline;
- procedure Put_UTF_8_Lines (S : in out Sink'Class; Item : UTF_8_Lines);
- -- Send data that is already UTF-8 encoded (including 7-bit ASCII) to
- -- S. These are more efficient than Put_String.
-
- procedure New_Line (S : in out Sink'Class) with
- Inline, Post => Column (S) = 1;
- -- Puts the new-line character.
-
- function Column (S : Sink'Class) return Positive with Inline;
- -- Current output column. The Column is initially 1, and is incremented for
- -- each 7-bit character output, except for the new-line character, which
- -- sets Column back to 1. The next character to be output will go in this
- -- column.
-
- procedure Tab_To_Column (S : in out Sink'Class; Column : Positive);
- -- Put spaces until we're at or past Column.
-
- procedure Set_Indentation (S : in out Sink'Class; Amount : Natural)
- with Inline;
- function Indentation (S : Sink'Class) return Natural with Inline;
- -- Indentation is initially 0. Set_Indentation sets it, and Indentation
- -- returns it. This number of space characters are put at the start of
- -- each nonempty line.
-
- subtype Optional_Indentation is Integer range -1 .. Natural'Last;
- Default : constant Optional_Indentation := -1;
-
- procedure Indent
- (S : in out Sink'Class; Amount : Optional_Indentation := Default)
- with Inline;
- procedure Outdent
- (S : in out Sink'Class; Amount : Optional_Indentation := Default)
- with Inline;
- -- Increase/decrease Indentation by Amount. If Amount = Default, the amount
- -- specified by the Indent_Amount parameter of the sink creation function
- -- is used. The sink creation functions are New_Buffer, Create_File, and
- -- Create_New_File.
-
-end Ada.Strings.Text_Output.Utils;
diff --git a/gcc/ada/libgnat/a-strfix.adb b/gcc/ada/libgnat/a-strfix.adb
index 8b7f043..ee72b6b 100644
--- a/gcc/ada/libgnat/a-strfix.adb
+++ b/gcc/ada/libgnat/a-strfix.adb
@@ -145,30 +145,26 @@ package body Ada.Strings.Fixed is
(Left : Natural;
Right : Character) return String
is
- Result : String (1 .. Left);
-
begin
- for J in Result'Range loop
- Result (J) := Right;
- end loop;
-
- return Result;
+ return Result : String (1 .. Left) do
+ for J in Result'Range loop
+ Result (J) := Right;
+ end loop;
+ end return;
end "*";
function "*"
(Left : Natural;
Right : String) return String
is
- Result : String (1 .. Left * Right'Length);
Ptr : Integer := 1;
-
begin
- for J in 1 .. Left loop
- Result (Ptr .. Ptr + Right'Length - 1) := Right;
- Ptr := Ptr + Right'Length;
- end loop;
-
- return Result;
+ return Result : String (1 .. Left * Right'Length) do
+ for J in 1 .. Left loop
+ Result (Ptr .. Ptr + Right'Length - 1) := Right;
+ Ptr := Ptr + Right'Length;
+ end loop;
+ end return;
end "*";
------------
@@ -180,6 +176,7 @@ package body Ada.Strings.Fixed is
From : Positive;
Through : Natural) return String
is
+ Front : Integer;
begin
if From > Through then
declare
@@ -207,18 +204,13 @@ package body Ada.Strings.Fixed is
end if;
else
- declare
- Front : constant Integer := From - Source'First;
- Result : String (1 .. Source'Length - (Through - From + 1));
-
- begin
+ Front := From - Source'First;
+ return Result : String (1 .. Source'Length - (Through - From + 1)) do
Result (1 .. Front) :=
Source (Source'First .. From - 1);
Result (Front + 1 .. Result'Last) :=
Source (Through + 1 .. Source'Last);
-
- return Result;
- end;
+ end return;
end if;
end Delete;
@@ -253,18 +245,13 @@ package body Ada.Strings.Fixed is
Result_Type (Source (Source'First .. Source'First + Count - 1));
else
- declare
- Result : Result_Type;
-
- begin
+ return Result : Result_Type do
Result (1 .. Source'Length) := Source;
for J in Source'Length + 1 .. Count loop
Result (J) := Pad;
end loop;
-
- return Result;
- end;
+ end return;
end if;
end Head;
@@ -291,7 +278,6 @@ package body Ada.Strings.Fixed is
Before : Positive;
New_Item : String) return String
is
- Result : String (1 .. Source'Length + New_Item'Length);
Front : constant Integer := Before - Source'First;
begin
@@ -299,14 +285,14 @@ package body Ada.Strings.Fixed is
raise Index_Error;
end if;
- Result (1 .. Front) :=
- Source (Source'First .. Before - 1);
- Result (Front + 1 .. Front + New_Item'Length) :=
- New_Item;
- Result (Front + New_Item'Length + 1 .. Result'Last) :=
- Source (Before .. Source'Last);
-
- return Result;
+ return Result : String (1 .. Source'Length + New_Item'Length) do
+ Result (1 .. Front) :=
+ Source (Source'First .. Before - 1);
+ Result (Front + 1 .. Front + New_Item'Length) :=
+ New_Item;
+ Result (Front + New_Item'Length + 1 .. Result'Last) :=
+ Source (Before .. Source'Last);
+ end return;
end Insert;
procedure Insert
@@ -435,8 +421,7 @@ package body Ada.Strings.Fixed is
function Overwrite
(Source : String;
Position : Positive;
- New_Item : String) return String
- is
+ New_Item : String) return String is
begin
if Position not in Source'First .. Source'Last + 1 then
raise Index_Error;
@@ -444,21 +429,17 @@ package body Ada.Strings.Fixed is
declare
Result_Length : constant Natural :=
- Integer'Max
- (Source'Length,
- Position - Source'First + New_Item'Length);
-
- Result : String (1 .. Result_Length);
- Front : constant Integer := Position - Source'First;
+ Integer'Max (Source'Length,
+ Position - Source'First + New_Item'Length);
+ Front : constant Integer := Position - Source'First;
begin
- Result (1 .. Front) :=
- Source (Source'First .. Position - 1);
- Result (Front + 1 .. Front + New_Item'Length) :=
- New_Item;
- Result (Front + New_Item'Length + 1 .. Result'Length) :=
- Source (Position + New_Item'Length .. Source'Last);
- return Result;
+ return Result : String (1 .. Result_Length) do
+ Result (1 .. Front) := Source (Source'First .. Position - 1);
+ Result (Front + 1 .. Front + New_Item'Length) := New_Item;
+ Result (Front + New_Item'Length + 1 .. Result'Length) :=
+ Source (Position + New_Item'Length .. Source'Last);
+ end return;
end;
end Overwrite;
@@ -495,24 +476,21 @@ package body Ada.Strings.Fixed is
Integer'Max (0, Low - Source'First);
-- Length of prefix of Source copied to result
- Back_Len : constant Integer :=
- Integer'Max (0, Source'Last - High);
+ Back_Len : constant Integer := Integer'Max (0, Source'Last - High);
-- Length of suffix of Source copied to result
Result_Length : constant Integer :=
Front_Len + By'Length + Back_Len;
-- Length of result
- Result : String (1 .. Result_Length);
-
begin
- Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
- Result (Front_Len + 1 .. Front_Len + By'Length) := By;
- Result (Front_Len + By'Length + 1 .. Result'Length) :=
- Source (High + 1 .. Source'Last);
- return Result;
+ return Result : String (1 .. Result_Length) do
+ Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
+ Result (Front_Len + 1 .. Front_Len + By'Length) := By;
+ Result (Front_Len + By'Length + 1 .. Result'Length) :=
+ Source (High + 1 .. Source'Last);
+ end return;
end;
-
else
return Insert (Source, Before => Low, New_Item => By);
end if;
@@ -549,17 +527,13 @@ package body Ada.Strings.Fixed is
-- Pad on left
else
- declare
- Result : Result_Type;
-
- begin
+ return Result : Result_Type do
for J in 1 .. Count - Source'Length loop
Result (J) := Pad;
end loop;
Result (Count - Source'Length + 1 .. Count) := Source;
- return Result;
- end;
+ end return;
end if;
end Tail;
@@ -585,14 +559,12 @@ package body Ada.Strings.Fixed is
(Source : String;
Mapping : Maps.Character_Mapping) return String
is
- Result : String (1 .. Source'Length);
-
begin
- for J in Source'Range loop
- Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
- end loop;
-
- return Result;
+ return Result : String (1 .. Source'Length) do
+ for J in Source'Range loop
+ Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
+ end loop;
+ end return;
end Translate;
procedure Translate
@@ -609,15 +581,13 @@ package body Ada.Strings.Fixed is
(Source : String;
Mapping : Maps.Character_Mapping_Function) return String
is
- Result : String (1 .. Source'Length);
pragma Unsuppress (Access_Check);
-
begin
- for J in Source'Range loop
- Result (J - (Source'First - 1)) := Mapping.all (Source (J));
- end loop;
-
- return Result;
+ return Result : String (1 .. Source'Length) do
+ for J in Source'Range loop
+ Result (J - (Source'First - 1)) := Mapping.all (Source (J));
+ end loop;
+ end return;
end Translate;
procedure Translate
diff --git a/gcc/ada/libgnat/a-strunb.ads b/gcc/ada/libgnat/a-strunb.ads
index 89c8339..13c7612 100644
--- a/gcc/ada/libgnat/a-strunb.ads
+++ b/gcc/ada/libgnat/a-strunb.ads
@@ -81,7 +81,7 @@ is
--------------------------------------------------------
function To_Unbounded_String
- (Source : String) return Unbounded_String
+ (Source : String) return Unbounded_String
with
Post => Length (To_Unbounded_String'Result) = Source'Length,
Global => null;
@@ -91,8 +91,7 @@ is
(Length : Natural) return Unbounded_String
with
Post =>
- Ada.Strings.Unbounded.Length (To_Unbounded_String'Result)
- = Length,
+ Ada.Strings.Unbounded.Length (To_Unbounded_String'Result) = Length,
Global => null;
-- Returns an Unbounded_String that represents an uninitialized String
-- whose length is Length.
@@ -524,11 +523,11 @@ is
with
Pre =>
Low - 1 <= Length (Source)
- and then (if High >= Low
- then Low - 1
- <= Natural'Last - By'Length
- - Natural'Max (Length (Source) - High, 0)
- else Length (Source) <= Natural'Last - By'Length),
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
Contract_Cases =>
(High >= Low =>
Length (Replace_Slice'Result)
@@ -545,11 +544,11 @@ is
with
Pre =>
Low - 1 <= Length (Source)
- and then (if High >= Low
- then Low - 1
- <= Natural'Last - By'Length
- - Natural'Max (Length (Source) - High, 0)
- else Length (Source) <= Natural'Last - By'Length),
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
Contract_Cases =>
(High >= Low =>
Length (Source)
@@ -586,7 +585,7 @@ is
Pre => Position - 1 <= Length (Source)
and then (if New_Item'Length /= 0
then
- New_Item'Length <= Natural'Last - (Position - 1)),
+ New_Item'Length <= Natural'Last - (Position - 1)),
Post =>
Length (Overwrite'Result)
= Natural'Max (Length (Source), Position - 1 + New_Item'Length),
@@ -600,7 +599,7 @@ is
Pre => Position - 1 <= Length (Source)
and then (if New_Item'Length /= 0
then
- New_Item'Length <= Natural'Last - (Position - 1)),
+ New_Item'Length <= Natural'Last - (Position - 1)),
Post =>
Length (Source)
= Natural'Max (Length (Source)'Old, Position - 1 + New_Item'Length),
diff --git a/gcc/ada/libgnat/a-strunb__shared.ads b/gcc/ada/libgnat/a-strunb__shared.ads
index 6382252..2091bde 100644
--- a/gcc/ada/libgnat/a-strunb__shared.ads
+++ b/gcc/ada/libgnat/a-strunb__shared.ads
@@ -363,9 +363,8 @@ is
Going : Direction := Forward;
Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
with
- Pre => (if Length (Source) /= 0
- then From <= Length (Source))
- and then Pattern'Length /= 0,
+ Pre => (if Length (Source) /= 0 then From <= Length (Source))
+ and then Pattern'Length /= 0,
Global => null;
pragma Ada_05 (Index);
@@ -376,11 +375,9 @@ is
Going : Direction := Forward;
Mapping : Maps.Character_Mapping_Function) return Natural
with
- Pre => (if Length (Source) /= 0
- then From <= Length (Source))
- and then Pattern'Length /= 0,
+ Pre => (if Length (Source) /= 0 then From <= Length (Source))
+ and then Pattern'Length /= 0,
Global => null;
-
pragma Ada_05 (Index);
function Index
diff --git a/gcc/ada/libgnat/a-sttebu.ads b/gcc/ada/libgnat/a-sttebu.ads
index 4f6fafc..39144a6 100644
--- a/gcc/ada/libgnat/a-sttebu.ads
+++ b/gcc/ada/libgnat/a-sttebu.ads
@@ -59,7 +59,8 @@ is
(Buffer : in out Root_Buffer_Type;
Amount : Text_Buffer_Count := Standard_Indent) with
Pre'Class => Current_Indent (Buffer) >= Amount
- or else raise Constraint_Error,
+ -- or else raise Constraint_Error,
+ or else Boolean'Val (Current_Indent (Buffer) - Amount),
Post'Class => Current_Indent (Buffer) =
Current_Indent (Buffer)'Old - Amount;
diff --git a/gcc/ada/libgnat/a-stteou.ads b/gcc/ada/libgnat/a-stteou.ads
deleted file mode 100644
index 324c9e6..0000000
--- a/gcc/ada/libgnat/a-stteou.ads
+++ /dev/null
@@ -1,193 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- ADA.STRINGS.TEXT_OUTPUT --
--- --
--- S p e c --
--- --
--- Copyright (C) 2020-2021, 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.Strings.UTF_Encoding;
-with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
-
-package Ada.Strings.Text_Output with Pure is
-
- -- This package provides a "Sink" abstraction, to which characters of type
- -- Character, Wide_Character, and Wide_Wide_Character can be sent. This
- -- type is used by the Put_Image attribute. In particular, T'Put_Image has
- -- the following parameter types:
- --
- -- procedure T'Put_Image (S : in out Sink'Class; V : T);
- --
- -- The default generated code for Put_Image of a composite type will
- -- typically call Put_Image on the components.
- --
- -- This is not a fully general abstraction that can be arbitrarily
- -- extended. It is designed with particular extensions in mind, and these
- -- extensions are declared in child packages of this package, because they
- -- depend on implementation details in the private part of this
- -- package.
- --
- -- Users are not expected to extend type Sink.
- --
- -- The primary extensions of Sink are:
- --
- -- Buffer. The characters sent to a Buffer are stored in memory, and can
- -- be retrieved via Get functions. This is intended for the
- -- implementation of the 'Image attribute. The compiler will generate a
- -- T'Image function that declares a local Buffer, sends characters to
- -- it, and then returns a call to Get, Destroying the Buffer on return.
- --
- -- function T'Image (V : T) return String is
- -- Buf : Buffer := New_Buffer (...);
- -- begin
- -- T'Put_Image (Buf, V);
- -- return Result : constant String := Get (Buf) do
- -- Destroy (Buf);
- -- end return;
- -- end T'Image;
- -- ????Perhaps Buffer should be controlled; if you don't like
- -- controlled types, call Put_Image directly.
- --
- -- File. The characters are sent to a file, possibly opened by file
- -- name, or possibly standard output or standard error. 'Put_Image
- -- can be called directly on a File, thus avoiding any heap allocation.
-
- type Sink (<>) is abstract tagged limited private;
- type Sink_Access is access all Sink'Class with Storage_Size => 0;
- -- Sink is a character sink; you can send characters to a Sink.
- -- UTF-8 encoding is used.
-
- procedure Full_Method (S : in out Sink) is abstract;
- procedure Flush_Method (S : in out Sink) is abstract;
- -- There is an internal buffer to store the characters. Full_Method is
- -- called when the buffer is full, and Flush_Method may be called to flush
- -- the buffer. For Buffer, Full_Method allocates more space for more
- -- characters, and Flush_Method does nothing. For File, Full_Method and
- -- Flush_Method do the same thing: write the characters to the file, and
- -- empty the internal buffer.
- --
- -- These are the only dispatching subprograms on Sink. This is for
- -- efficiency; we don't dispatch on every write to the Sink, but only when
- -- the internal buffer is full (or upon client request).
- --
- -- Full_Method and Flush_Method must make the current chunk empty.
- --
- -- Additional operations operating on Sink'Class are declared in the Utils
- -- child, including Full and Flush, which call the above.
-
- function To_Wide (C : Character) return Wide_Character is
- (Wide_Character'Val (Character'Pos (C)));
- function To_Wide_Wide (C : Character) return Wide_Wide_Character is
- (Wide_Wide_Character'Val (Character'Pos (C)));
- function To_Wide_Wide (C : Wide_Character) return Wide_Wide_Character is
- (Wide_Wide_Character'Val (Wide_Character'Pos (C)));
- -- Conversions [Wide_]Character --> [Wide_]Wide_Character.
- -- These cannot fail.
-
- function From_Wide (C : Wide_Character) return Character is
- (Character'Val (Wide_Character'Pos (C)));
- function From_Wide_Wide (C : Wide_Wide_Character) return Character is
- (Character'Val (Wide_Wide_Character'Pos (C)));
- function From_Wide_Wide (C : Wide_Wide_Character) return Wide_Character is
- (Wide_Character'Val (Wide_Wide_Character'Pos (C)));
- -- Conversions [Wide_]Wide_Character --> [Wide_]Character.
- -- These fail if the character is out of range.
-
- function NL return Character is (ASCII.LF) with Inline;
- function Wide_NL return Wide_Character is (To_Wide (Character'(NL)))
- with Inline;
- function Wide_Wide_NL return Wide_Wide_Character is
- (To_Wide_Wide (Character'(NL))) with Inline;
- -- Character representing new line. There is no support for CR/LF line
- -- endings.
-
- -- We have two subtypes of String that are encoded in UTF-8. UTF_8 cannot
- -- contain newline characters; UTF_8_Lines can. Sending UTF_8 data to a
- -- Sink is more efficient, because end-of-line processing is not needed.
- -- Both of these are more efficient than [[Wide_]Wide_]String, because no
- -- encoding is needed.
-
- subtype UTF_8_Lines is UTF_Encoding.UTF_8_String with
- Predicate =>
- UTF_Encoding.Wide_Wide_Strings.Encode
- (UTF_Encoding.Wide_Wide_Strings.Decode (UTF_8_Lines)) = UTF_8_Lines;
-
- subtype UTF_8 is UTF_8_Lines with
- Predicate => (for all UTF_8_Char of UTF_8 => UTF_8_Char /= NL);
-
- Default_Indent_Amount : constant Natural := 4;
-
- Default_Chunk_Length : constant Positive := 500;
- -- Experiment shows this value to be reasonably efficient; decreasing it
- -- slows things down, but increasing it doesn't gain much.
-
-private
- -- For Buffer, the "internal buffer" mentioned above is implemented as a
- -- linked list of chunks. When the current chunk is full, we allocate a new
- -- one. For File, there is only one chunk. When it is full, we send the
- -- data to the file, and empty it.
-
- type Chunk;
- type Chunk_Access is access all Chunk with Storage_Size => 0;
- type Chunk (Length : Positive) is limited record
- Next : Chunk_Access := null;
- Chars : UTF_8_Lines (1 .. Length);
- end record;
-
- type Sink (Chunk_Length : Positive) is abstract tagged limited record
- Indent_Amount : Natural;
- Column : Positive := 1;
- Indentation : Natural := 0;
-
- All_7_Bits : Boolean := True;
- -- For optimization of Text_Output.Buffers.Get (cf).
- -- True if all characters seen so far fit in 7 bits.
- -- 7-bit characters are represented the same in Character
- -- and in UTF-8, so they don't need translation.
-
- All_8_Bits : Boolean := True;
- -- True if all characters seen so far fit in 8 bits.
- -- This is needed in Text_Output.Buffers.Get to distinguish
- -- the case where all characters are Latin-1 (so it should
- -- decode) from the case where some characters are bigger than
- -- 8 bits (so the result is implementation defined).
-
- Cur_Chunk : Chunk_Access;
- -- Points to the chunk we are currently sending characters to.
- -- We want to say:
- -- Cur_Chunk : Chunk_Access := Initial_Chunk'Access;
- -- but that's illegal, so we have some horsing around to do.
-
- Last : Natural := 0;
- -- Last-used character in Cur_Chunk.all.
-
- Initial_Chunk : aliased Chunk (Length => Chunk_Length);
- -- For Buffer, this is the first chunk. Subsequent chunks are allocated
- -- on the heap. For File, this is the only chunk, and there is no heap
- -- allocation.
- end record;
-
-end Ada.Strings.Text_Output;
diff --git a/gcc/ada/libgnat/a-textio.adb b/gcc/ada/libgnat/a-textio.adb
index dc67091..717f529 100644
--- a/gcc/ada/libgnat/a-textio.adb
+++ b/gcc/ada/libgnat/a-textio.adb
@@ -171,15 +171,15 @@ is
-- is required (RM A.10.3(23)) but it seems reasonable, and besides
-- ACVC test CE3208A expects this behavior.
- if File_Type (File) = Current_In then
+ if File = Current_In then
Current_In := null;
- elsif File_Type (File) = Current_Out then
+ elsif File = Current_Out then
Current_Out := null;
- elsif File_Type (File) = Current_Err then
+ elsif File = Current_Err then
Current_Err := null;
end if;
- Terminate_Line (File_Type (File));
+ Terminate_Line (File.all'Access);
end AFCB_Close;
---------------
@@ -187,10 +187,9 @@ is
---------------
procedure AFCB_Free (File : not null access Text_AFCB) is
- type FCB_Ptr is access all Text_AFCB;
- FT : FCB_Ptr := FCB_Ptr (File);
+ FT : File_Type := File.all'Access;
- procedure Free is new Ada.Unchecked_Deallocation (Text_AFCB, FCB_Ptr);
+ procedure Free is new Ada.Unchecked_Deallocation (Text_AFCB, File_Type);
begin
Free (FT);
diff --git a/gcc/ada/libgnat/a-uncdea.ads b/gcc/ada/libgnat/a-uncdea.ads
index a61cd50..439fa61 100644
--- a/gcc/ada/libgnat/a-uncdea.ads
+++ b/gcc/ada/libgnat/a-uncdea.ads
@@ -17,7 +17,10 @@ generic
type Object (<>) is limited private;
type Name is access Object;
-procedure Ada.Unchecked_Deallocation (X : in out Name);
+procedure Ada.Unchecked_Deallocation (X : in out Name) with
+ Depends => (X => null, -- X on exit does not depend on its input value
+ null => X), -- X's input value has no effect
+ Post => X = null; -- X's output value is null
pragma Preelaborate (Unchecked_Deallocation);
pragma Import (Intrinsic, Ada.Unchecked_Deallocation);
diff --git a/gcc/ada/libgnat/a-witeio.adb b/gcc/ada/libgnat/a-witeio.adb
index dbd3fc8..7dbd3b3 100644
--- a/gcc/ada/libgnat/a-witeio.adb
+++ b/gcc/ada/libgnat/a-witeio.adb
@@ -136,15 +136,15 @@ package body Ada.Wide_Text_IO is
-- is required (RM A.10.3(23)) but it seems reasonable, and besides
-- ACVC test CE3208A expects this behavior.
- if File_Type (File) = Current_In then
+ if File = Current_In then
Current_In := null;
- elsif File_Type (File) = Current_Out then
+ elsif File = Current_Out then
Current_Out := null;
- elsif File_Type (File) = Current_Err then
+ elsif File = Current_Err then
Current_Err := null;
end if;
- Terminate_Line (File_Type (File));
+ Terminate_Line (File.all'Access);
end AFCB_Close;
---------------
@@ -152,11 +152,10 @@ package body Ada.Wide_Text_IO is
---------------
procedure AFCB_Free (File : not null access Wide_Text_AFCB) is
- type FCB_Ptr is access all Wide_Text_AFCB;
- FT : FCB_Ptr := FCB_Ptr (File);
+ FT : File_Type := File.all'Access;
procedure Free is
- new Ada.Unchecked_Deallocation (Wide_Text_AFCB, FCB_Ptr);
+ new Ada.Unchecked_Deallocation (Wide_Text_AFCB, File_Type);
begin
Free (FT);
diff --git a/gcc/ada/libgnat/a-ztexio.adb b/gcc/ada/libgnat/a-ztexio.adb
index 0dfabd5..71d733e 100644
--- a/gcc/ada/libgnat/a-ztexio.adb
+++ b/gcc/ada/libgnat/a-ztexio.adb
@@ -136,15 +136,15 @@ package body Ada.Wide_Wide_Text_IO is
-- is required (RM A.10.3(23)) but it seems reasonable, and besides
-- ACVC test CE3208A expects this behavior.
- if File_Type (File) = Current_In then
+ if File = Current_In then
Current_In := null;
- elsif File_Type (File) = Current_Out then
+ elsif File = Current_Out then
Current_Out := null;
- elsif File_Type (File) = Current_Err then
+ elsif File = Current_Err then
Current_Err := null;
end if;
- Terminate_Line (File_Type (File));
+ Terminate_Line (File.all'Access);
end AFCB_Close;
---------------
@@ -152,11 +152,10 @@ package body Ada.Wide_Wide_Text_IO is
---------------
procedure AFCB_Free (File : not null access Wide_Wide_Text_AFCB) is
- type FCB_Ptr is access all Wide_Wide_Text_AFCB;
- FT : FCB_Ptr := FCB_Ptr (File);
+ FT : File_Type := File.all'Access;
procedure Free is new
- Ada.Unchecked_Deallocation (Wide_Wide_Text_AFCB, FCB_Ptr);
+ Ada.Unchecked_Deallocation (Wide_Wide_Text_AFCB, File_Type);
begin
Free (FT);
diff --git a/gcc/ada/libgnat/g-debpoo.adb b/gcc/ada/libgnat/g-debpoo.adb
index 40e5279..0092139 100644
--- a/gcc/ada/libgnat/g-debpoo.adb
+++ b/gcc/ada/libgnat/g-debpoo.adb
@@ -362,7 +362,7 @@ package body GNAT.Debug_Pools is
-- These procedures are used as markers when computing the stacktraces,
-- so that addresses in the debug pool itself are not reported to the user.
- Code_Address_For_Allocate_End : System.Address;
+ Code_Address_For_Allocate_End : System.Address := System.Null_Address;
Code_Address_For_Deallocate_End : System.Address;
Code_Address_For_Dereference_End : System.Address;
-- Taking the address of the above procedures will not work on some
diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb
index ec4cf29..75a2b27 100644
--- a/gcc/ada/libgnat/g-socket.adb
+++ b/gcc/ada/libgnat/g-socket.adb
@@ -96,6 +96,9 @@ package body GNAT.Sockets is
Options : constant array (Specific_Option_Name) of C.int :=
(Keep_Alive => SOSC.SO_KEEPALIVE,
+ Keep_Alive_Count => SOSC.TCP_KEEPCNT,
+ Keep_Alive_Idle => SOSC.TCP_KEEPIDLE,
+ Keep_Alive_Interval => SOSC.TCP_KEEPINTVL,
Reuse_Address => SOSC.SO_REUSEADDR,
Broadcast => SOSC.SO_BROADCAST,
Send_Buffer => SOSC.SO_SNDBUF,
@@ -1442,6 +1445,9 @@ package body GNAT.Sockets is
| Error
| Generic_Option
| Keep_Alive
+ | Keep_Alive_Count
+ | Keep_Alive_Idle
+ | Keep_Alive_Interval
| Multicast_If_V4
| Multicast_If_V6
| Multicast_Loop_V4
@@ -1511,6 +1517,15 @@ package body GNAT.Sockets is
=>
Opt.Enabled := (V4 /= 0);
+ when Keep_Alive_Count =>
+ Opt.Count := Natural (V4);
+
+ when Keep_Alive_Idle =>
+ Opt.Idle_Seconds := Natural (V4);
+
+ when Keep_Alive_Interval =>
+ Opt.Interval_Seconds := Natural (V4);
+
when Busy_Polling =>
Opt.Microseconds := Natural (V4);
@@ -1555,14 +1570,18 @@ package body GNAT.Sockets is
| Send_Timeout
=>
if Is_Windows then
-
- -- Timeout is in milliseconds, actual value is 500 ms +
- -- returned value (unless it is 0).
-
if U4 = 0 then
Opt.Timeout := 0.0;
+
else
- Opt.Timeout := Duration (U4) / 1000 + 0.500;
+ if Minus_500ms_Windows_Timeout then
+ -- Timeout is in milliseconds, actual value is 500 ms +
+ -- returned value (unless it is 0).
+
+ U4 := U4 + 500;
+ end if;
+
+ Opt.Timeout := Duration (U4) / 1000;
end if;
else
@@ -2620,6 +2639,21 @@ package body GNAT.Sockets is
Len := V4'Size / 8;
Add := V4'Address;
+ when Keep_Alive_Count =>
+ V4 := C.int (Option.Count);
+ Len := V4'Size / 8;
+ Add := V4'Address;
+
+ when Keep_Alive_Idle =>
+ V4 := C.int (Option.Idle_Seconds);
+ Len := V4'Size / 8;
+ Add := V4'Address;
+
+ when Keep_Alive_Interval =>
+ V4 := C.int (Option.Interval_Seconds);
+ Len := V4'Size / 8;
+ Add := V4'Address;
+
when Busy_Polling =>
V4 := C.int (Option.Microseconds);
Len := V4'Size / 8;
@@ -2694,7 +2728,7 @@ package body GNAT.Sockets is
Len := U4'Size / 8;
Add := U4'Address;
- U4 := C.unsigned (Option.Timeout / 0.001);
+ U4 := C.unsigned (Option.Timeout * 1000);
if Option.Timeout > 0.0 and then U4 = 0 then
-- Avoid round to zero. Zero timeout mean unlimited
diff --git a/gcc/ada/libgnat/g-socket.ads b/gcc/ada/libgnat/g-socket.ads
index 03afd36..4372f3e 100644
--- a/gcc/ada/libgnat/g-socket.ads
+++ b/gcc/ada/libgnat/g-socket.ads
@@ -845,11 +845,20 @@ package GNAT.Sockets is
-- IP_Protocol_For_TCP_Level --
-------------------------------
- No_Delay, -- TCP_NODELAY
+ No_Delay, -- TCP_NODELAY
-- Disable the Nagle algorithm. This means that output buffer content
-- is always sent as soon as possible, even if there is only a small
-- amount of data.
+ Keep_Alive_Count, -- TCP_KEEPCNT
+ -- Maximum number of keepalive probes
+
+ Keep_Alive_Idle, -- TCP_KEEPIDLE
+ -- Idle time before TCP starts sending keepalive probes
+
+ Keep_Alive_Interval, -- TCP_KEEPINTVL
+ -- Time between individual keepalive probes
+
------------------------------
-- IP_Protocol_For_IP_Level --
------------------------------
@@ -923,26 +932,35 @@ package GNAT.Sockets is
Enabled : Boolean;
case Name is
- when Linger =>
+ when Linger =>
Seconds : Natural;
- when others =>
+ when others =>
null;
end case;
- when Busy_Polling =>
+ when Keep_Alive_Count =>
+ Count : Natural;
+
+ when Keep_Alive_Idle =>
+ Idle_Seconds : Natural;
+
+ when Keep_Alive_Interval =>
+ Interval_Seconds : Natural;
+
+ when Busy_Polling =>
Microseconds : Natural;
- when Send_Buffer |
- Receive_Buffer =>
+ when Send_Buffer |
+ Receive_Buffer =>
Size : Natural;
- when Error =>
+ when Error =>
Error : Error_Type;
- when Add_Membership_V4 |
- Add_Membership_V6 |
- Drop_Membership_V4 |
- Drop_Membership_V6 =>
+ when Add_Membership_V4 |
+ Add_Membership_V6 |
+ Drop_Membership_V4 |
+ Drop_Membership_V6 =>
Multicast_Address : Inet_Addr_Type;
case Name is
when Add_Membership_V4 |
@@ -958,13 +976,13 @@ package GNAT.Sockets is
when Multicast_If_V6 =>
Outgoing_If_Index : Natural;
- when Multicast_TTL =>
+ when Multicast_TTL =>
Time_To_Live : Natural;
- when Multicast_Hops =>
+ when Multicast_Hops =>
Hop_Limit : Integer range -1 .. 255;
- when Send_Timeout |
+ when Send_Timeout |
Receive_Timeout =>
Timeout : Timeval_Duration;
diff --git a/gcc/ada/libgnat/g-sothco.ads b/gcc/ada/libgnat/g-sothco.ads
index f6e61b2..b48657b 100644
--- a/gcc/ada/libgnat/g-sothco.ads
+++ b/gcc/ada/libgnat/g-sothco.ads
@@ -34,6 +34,7 @@
with Ada.Unchecked_Conversion;
with Interfaces.C.Strings;
+with System.Parameters;
package GNAT.Sockets.Thin_Common is
@@ -44,9 +45,9 @@ package GNAT.Sockets.Thin_Common is
Failure : constant C.int := -1;
type time_t is
- range -2 ** (8 * SOSC.SIZEOF_tv_sec - 1)
- .. 2 ** (8 * SOSC.SIZEOF_tv_sec - 1) - 1;
- for time_t'Size use 8 * SOSC.SIZEOF_tv_sec;
+ range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
+ for time_t'Size use System.Parameters.time_t_bits;
pragma Convention (C, time_t);
type suseconds_t is
diff --git a/gcc/ada/libgnat/s-atocou.ads b/gcc/ada/libgnat/s-atocou.ads
index a75173a..9488b6d 100644
--- a/gcc/ada/libgnat/s-atocou.ads
+++ b/gcc/ada/libgnat/s-atocou.ads
@@ -101,7 +101,6 @@ private
type Atomic_Counter is record
Value : aliased Atomic_Unsigned := 1;
- pragma Atomic (Value);
end record;
end System.Atomic_Counters;
diff --git a/gcc/ada/libgnat/s-atocou__builtin.adb b/gcc/ada/libgnat/s-atocou__builtin.adb
index 2ca8b9e..d87f9ad 100644
--- a/gcc/ada/libgnat/s-atocou__builtin.adb
+++ b/gcc/ada/libgnat/s-atocou__builtin.adb
@@ -51,24 +51,19 @@ package body System.Atomic_Counters is
procedure Decrement (Item : aliased in out Atomic_Unsigned) is
begin
- if Sync_Sub_And_Fetch (Item'Unrestricted_Access, 1) = 0 then
+ if Sync_Sub_And_Fetch (Item'Unchecked_Access, 1) = 0 then
null;
end if;
end Decrement;
function Decrement (Item : aliased in out Atomic_Unsigned) return Boolean is
begin
- return Sync_Sub_And_Fetch (Item'Unrestricted_Access, 1) = 0;
+ return Sync_Sub_And_Fetch (Item'Unchecked_Access, 1) = 0;
end Decrement;
function Decrement (Item : in out Atomic_Counter) return Boolean is
begin
- -- Note: the use of Unrestricted_Access here is required because we
- -- are obtaining an access-to-volatile pointer to a non-volatile object.
- -- This is not allowed for [Unchecked_]Access, but is safe in this case
- -- because we know that no aliases are being created.
-
- return Sync_Sub_And_Fetch (Item.Value'Unrestricted_Access, 1) = 0;
+ return Sync_Sub_And_Fetch (Item.Value'Unchecked_Access, 1) = 0;
end Decrement;
---------------
@@ -77,17 +72,12 @@ package body System.Atomic_Counters is
procedure Increment (Item : aliased in out Atomic_Unsigned) is
begin
- Sync_Add_And_Fetch (Item'Unrestricted_Access, 1);
+ Sync_Add_And_Fetch (Item'Unchecked_Access, 1);
end Increment;
procedure Increment (Item : in out Atomic_Counter) is
begin
- -- Note: the use of Unrestricted_Access here is required because we are
- -- obtaining an access-to-volatile pointer to a non-volatile object.
- -- This is not allowed for [Unchecked_]Access, but is safe in this case
- -- because we know that no aliases are being created.
-
- Sync_Add_And_Fetch (Item.Value'Unrestricted_Access, 1);
+ Sync_Add_And_Fetch (Item.Value'Unchecked_Access, 1);
end Increment;
----------------
diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb
index 5c02b2d..19f4cf7 100644
--- a/gcc/ada/libgnat/s-os_lib.adb
+++ b/gcc/ada/libgnat/s-os_lib.adb
@@ -133,42 +133,6 @@ package body System.OS_Lib is
-- Converts a C String to an Ada String. We could do this making use of
-- Interfaces.C.Strings but we prefer not to import that entire package
- ---------
- -- "<" --
- ---------
-
- function "<" (X, Y : OS_Time) return Boolean is
- begin
- return Long_Integer (X) < Long_Integer (Y);
- end "<";
-
- ----------
- -- "<=" --
- ----------
-
- function "<=" (X, Y : OS_Time) return Boolean is
- begin
- return Long_Integer (X) <= Long_Integer (Y);
- end "<=";
-
- ---------
- -- ">" --
- ---------
-
- function ">" (X, Y : OS_Time) return Boolean is
- begin
- return Long_Integer (X) > Long_Integer (Y);
- end ">";
-
- ----------
- -- ">=" --
- ----------
-
- function ">=" (X, Y : OS_Time) return Boolean is
- begin
- return Long_Integer (X) >= Long_Integer (Y);
- end ">=";
-
-----------------
-- Args_Length --
-----------------
@@ -1347,13 +1311,13 @@ package body System.OS_Lib is
Second : out Second_Type)
is
procedure To_GM_Time
- (P_Time_T : Address;
- P_Year : Address;
- P_Month : Address;
- P_Day : Address;
- P_Hours : Address;
- P_Mins : Address;
- P_Secs : Address);
+ (P_OS_Time : Address;
+ P_Year : Address;
+ P_Month : Address;
+ P_Day : Address;
+ P_Hours : Address;
+ P_Mins : Address;
+ P_Secs : Address);
pragma Import (C, To_GM_Time, "__gnat_to_gm_time");
T : OS_Time := Date;
@@ -1385,13 +1349,13 @@ package body System.OS_Lib is
Locked_Processing : begin
SSL.Lock_Task.all;
To_GM_Time
- (P_Time_T => T'Address,
- P_Year => Y'Address,
- P_Month => Mo'Address,
- P_Day => D'Address,
- P_Hours => H'Address,
- P_Mins => Mn'Address,
- P_Secs => S'Address);
+ (P_OS_Time => T'Address,
+ P_Year => Y'Address,
+ P_Month => Mo'Address,
+ P_Day => D'Address,
+ P_Hours => H'Address,
+ P_Mins => Mn'Address,
+ P_Secs => S'Address);
SSL.Unlock_Task.all;
exception
@@ -1429,26 +1393,26 @@ package body System.OS_Lib is
Second : Second_Type) return OS_Time
is
procedure To_OS_Time
- (P_Time_T : Address;
- P_Year : Integer;
- P_Month : Integer;
- P_Day : Integer;
- P_Hours : Integer;
- P_Mins : Integer;
- P_Secs : Integer);
+ (P_OS_Time : Address;
+ P_Year : Integer;
+ P_Month : Integer;
+ P_Day : Integer;
+ P_Hours : Integer;
+ P_Mins : Integer;
+ P_Secs : Integer);
pragma Import (C, To_OS_Time, "__gnat_to_os_time");
Result : OS_Time;
begin
To_OS_Time
- (P_Time_T => Result'Address,
- P_Year => Year - 1900,
- P_Month => Month - 1,
- P_Day => Day,
- P_Hours => Hour,
- P_Mins => Minute,
- P_Secs => Second);
+ (P_OS_Time => Result'Address,
+ P_Year => Year - 1900,
+ P_Month => Month - 1,
+ P_Day => Day,
+ P_Hours => Hour,
+ P_Mins => Minute,
+ P_Secs => Second);
return Result;
end GM_Time_Of;
diff --git a/gcc/ada/libgnat/s-os_lib.ads b/gcc/ada/libgnat/s-os_lib.ads
index 42ac488..2049e38 100644
--- a/gcc/ada/libgnat/s-os_lib.ads
+++ b/gcc/ada/libgnat/s-os_lib.ads
@@ -164,8 +164,21 @@ package System.OS_Lib is
-- component parts to be interpreted in the local time zone, and returns
-- an OS_Time. Returns Invalid_Time if the creation fails.
- subtype time_t is Long_Integer;
- -- C time_t type of the time representation
+ ------------------
+ -- Time_t Stuff --
+ ------------------
+
+ -- Note: Do not use time_t in the compiler and host-based tools; instead
+ -- use OS_Time. These 3 declarations are intended for use only by consumers
+ -- of the GNAT.OS_Lib renaming of this package.
+
+ subtype time_t is Long_Long_Integer;
+ -- C time_t can be either long or long long, but this is a subtype not used
+ -- in the compiler or tools, but only for user applications, so we choose
+ -- the Ada equivalent of the latter because eventually that will be the
+ -- type used out of necessity. This may affect some user code on 32-bit
+ -- targets that have not yet migrated to the Posix 2008 standard,
+ -- particularly pre version 5 32-bit Linux.
function To_C (Time : OS_Time) return time_t;
-- Convert OS_Time to C time_t type
@@ -1098,24 +1111,18 @@ private
pragma Import (C, Current_Process_Id, "__gnat_current_process_id");
type OS_Time is
- range -(2 ** (Standard'Address_Size - Integer'(1))) ..
- +(2 ** (Standard'Address_Size - Integer'(1)) - 1);
+ range -(2 ** 63) .. +(2 ** 63 - 1);
-- Type used for timestamps in the compiler. This type is used to hold
-- time stamps, but may have a different representation than C's time_t.
-- This type needs to match the declaration of OS_Time in adaint.h.
- -- Add pragma Inline statements for comparison operations on OS_Time. It
- -- would actually be nice to use pragma Import (Intrinsic) here, but this
- -- was not properly supported till GNAT 3.15a, so that would cause
- -- bootstrap path problems. To be changed later ???
-
Invalid_Time : constant OS_Time := -1;
-- This value should match the return value from __gnat_file_time_*
- pragma Inline ("<");
- pragma Inline (">");
- pragma Inline ("<=");
- pragma Inline (">=");
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">=");
pragma Inline (To_C);
pragma Inline (To_Ada);
diff --git a/gcc/ada/libgnat/s-osprim__darwin.adb b/gcc/ada/libgnat/s-osprim__darwin.adb
index adbd7ed..00d0ccb 100644
--- a/gcc/ada/libgnat/s-osprim__darwin.adb
+++ b/gcc/ada/libgnat/s-osprim__darwin.adb
@@ -31,6 +31,7 @@
-- This version is for darwin
+with System.Parameters;
package body System.OS_Primitives is
-- ??? These definitions are duplicated from System.OS_Interface
@@ -45,7 +46,8 @@ package body System.OS_Primitives is
pragma Convention (C, struct_timezone);
type struct_timezone_ptr is access all struct_timezone;
- type time_t is new Long_Integer;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type struct_timeval is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnat/s-osprim__posix.adb b/gcc/ada/libgnat/s-osprim__posix.adb
index d3083dd..96bf70e 100644
--- a/gcc/ada/libgnat/s-osprim__posix.adb
+++ b/gcc/ada/libgnat/s-osprim__posix.adb
@@ -30,6 +30,7 @@
------------------------------------------------------------------------------
-- This version is for POSIX-like operating systems
+with System.Parameters;
package body System.OS_Primitives is
@@ -38,7 +39,8 @@ package body System.OS_Primitives is
-- these declarations in System.OS_Interface and move these ones in
-- the spec.
- type time_t is new Long_Integer;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnat/s-osprim__posix2008.adb b/gcc/ada/libgnat/s-osprim__posix2008.adb
index 4804f0b..44f14c4f 100644
--- a/gcc/ada/libgnat/s-osprim__posix2008.adb
+++ b/gcc/ada/libgnat/s-osprim__posix2008.adb
@@ -33,6 +33,7 @@
with System.CRTL;
with System.OS_Constants;
+with System.Parameters;
package body System.OS_Primitives is
subtype int is System.CRTL.int;
@@ -41,7 +42,8 @@ package body System.OS_Primitives is
-- we don't want to depend on any package. Consider removing these
-- declarations in System.OS_Interface and move these ones to the spec.
- type time_t is new System.CRTL.int64;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnat/s-osprim__rtems.adb b/gcc/ada/libgnat/s-osprim__rtems.adb
index f7a7e1f..23669e1 100644
--- a/gcc/ada/libgnat/s-osprim__rtems.adb
+++ b/gcc/ada/libgnat/s-osprim__rtems.adb
@@ -31,6 +31,7 @@
-- This version is for POSIX-like operating systems
+with System.Parameters;
package body System.OS_Primitives is
-- ??? These definitions are duplicated from System.OS_Interface
@@ -38,7 +39,8 @@ package body System.OS_Primitives is
-- these declarations in System.OS_Interface and move these ones in
-- the spec.
- type time_t is new Long_Long_Integer;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnat/s-osprim__x32.adb b/gcc/ada/libgnat/s-osprim__x32.adb
index 846ca11..d3c922c 100644
--- a/gcc/ada/libgnat/s-osprim__x32.adb
+++ b/gcc/ada/libgnat/s-osprim__x32.adb
@@ -38,7 +38,8 @@ package body System.OS_Primitives is
-- these declarations in System.OS_Interface and move these ones in
-- the spec.
- type time_t is new Long_Long_Integer;
+ type time_t is range -2 ** (System.Parameters.time_t_bits - 1)
+ .. 2 ** (System.Parameters.time_t_bits - 1) - 1;
type timespec is record
tv_sec : time_t;
diff --git a/gcc/ada/libgnat/s-parame.ads b/gcc/ada/libgnat/s-parame.ads
index d767f8d..0f76a65 100644
--- a/gcc/ada/libgnat/s-parame.ads
+++ b/gcc/ada/libgnat/s-parame.ads
@@ -100,6 +100,13 @@ package System.Parameters is
-- Indicates if secondary stacks can grow and shrink at run-time. If False,
-- the size of a secondary stack is fixed at the point of its creation.
+ ------------------------------------
+ -- Characteristics of time_t type --
+ ------------------------------------
+
+ time_t_bits : constant := Long_Integer'Size;
+ -- Number of bits in type time_t
+
----------------------------------------------
-- Characteristics of types in Interfaces.C --
----------------------------------------------
diff --git a/gcc/ada/libgnat/s-parame__ae653.ads b/gcc/ada/libgnat/s-parame__ae653.ads
index c42c97c..f838b41 100644
--- a/gcc/ada/libgnat/s-parame__ae653.ads
+++ b/gcc/ada/libgnat/s-parame__ae653.ads
@@ -100,6 +100,13 @@ package System.Parameters is
-- Indicates if secondary stacks can grow and shrink at run-time. If False,
-- the size of a secondary stack is fixed at the point of its creation.
+ ------------------------------------
+ -- Characteristics of time_t type --
+ ------------------------------------
+
+ time_t_bits : constant := Long_Integer'Size;
+ -- Number of bits in type time_t
+
----------------------------------------------
-- Characteristics of types in Interfaces.C --
----------------------------------------------
diff --git a/gcc/ada/libgnat/s-parame__hpux.ads b/gcc/ada/libgnat/s-parame__hpux.ads
index 961c9ce..d6d4e10 100644
--- a/gcc/ada/libgnat/s-parame__hpux.ads
+++ b/gcc/ada/libgnat/s-parame__hpux.ads
@@ -98,6 +98,13 @@ package System.Parameters is
-- Indicates if secondary stacks can grow and shrink at run-time. If False,
-- the size of a secondary stack is fixed at the point of its creation.
+ ------------------------------------
+ -- Characteristics of time_t type --
+ ------------------------------------
+
+ time_t_bits : constant := Long_Integer'Size;
+ -- Number of bits in type time_t
+
----------------------------------------------
-- Characteristics of Types in Interfaces.C --
----------------------------------------------
diff --git a/gcc/ada/libgnat/s-parame__posix2008.ads b/gcc/ada/libgnat/s-parame__posix2008.ads
new file mode 100644
index 0000000..af299ec
--- /dev/null
+++ b/gcc/ada/libgnat/s-parame__posix2008.ads
@@ -0,0 +1,193 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2021, 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 is the Posix 2008 version for 64 bit time_t.
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+pragma Compiler_Unit_Warning;
+
+package System.Parameters is
+ pragma Pure;
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Size_Type is range
+ -(2 ** (Integer'(Standard'Address_Size) - 1)) ..
+ +(2 ** (Integer'(Standard'Address_Size) - 1)) - 1;
+ -- Type used to provide task stack sizes to the runtime. Sized to permit
+ -- stack sizes of up to half the total addressable memory space. This may
+ -- seem excessively large (even for 32-bit systems), however there are many
+ -- instances of users requiring large stack sizes (for example string
+ -- processing).
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 8_192_000;
+ -- Assumed size of the environment task, if no other information is
+ -- available. This value is used when stack checking is enabled and
+ -- no GNAT_STACK_LIMIT environment variable is set.
+
+ Stack_Grows_Down : constant Boolean := True;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ Runtime_Default_Sec_Stack_Size : constant Size_Type := 10 * 1024;
+ -- The run-time chosen default size for secondary stacks that may be
+ -- overridden by the user with the use of binder -D switch.
+
+ Sec_Stack_Dynamic : constant Boolean := True;
+ -- Indicates if secondary stacks can grow and shrink at run-time. If False,
+ -- the size of a secondary stack is fixed at the point of its creation.
+
+ ------------------------------------
+ -- Characteristics of time_t type --
+ ------------------------------------
+
+ time_t_bits : constant := Long_Long_Integer'Size;
+ -- Number of bits in type time_t. Use for targets that are Posix 2008
+ -- compliant (fixes the year 2038 time_t overflow).
+
+ ----------------------------------------------
+ -- Characteristics of types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := Long_Integer'Size;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this may not be true
+ -- of all targets.
+
+ ptr_bits : constant := Standard'Address_Size;
+ subtype C_Address is System.Address;
+ -- Number of bits in Interfaces.C pointers, normally a standard address
+
+ C_Malloc_Linkname : constant String := "__gnat_malloc";
+ -- Name of runtime function used to allocate such a pointer
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are omitted only for outer level objects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := False;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Max_Attribute_Count : constant := 32;
+ -- Number of task attributes stored in the task control block
+
+ -----------------------
+ -- Task Image Length --
+ -----------------------
+
+ Max_Task_Image_Length : constant := 256;
+ -- This constant specifies the maximum length of a task's image
+
+ ------------------------------
+ -- Exception Message Length --
+ ------------------------------
+
+ Default_Exception_Msg_Max_Length : constant := 200;
+ -- This constant specifies the default number of characters to allow
+ -- in an exception message (200 is minimum required by RM 11.4.1(18)).
+
+end System.Parameters;
diff --git a/gcc/ada/libgnat/s-parame__vxworks.ads b/gcc/ada/libgnat/s-parame__vxworks.ads
index 8598a43..11b408b 100644
--- a/gcc/ada/libgnat/s-parame__vxworks.ads
+++ b/gcc/ada/libgnat/s-parame__vxworks.ads
@@ -100,6 +100,21 @@ package System.Parameters is
-- Indicates if secondary stacks can grow and shrink at run-time. If False,
-- the size of a secondary stack is fixed at the point of its creation.
+ ------------------------------------
+ -- Characteristics of time_t type --
+ ------------------------------------
+
+ -- IMPORTANT NOTE:
+ -- Select the appropriate time_t_bits for the VSB in use, then rebuild
+ -- the runtime using instructions in adainclude/libada.gpr.
+
+ time_t_bits : constant := Long_Integer'Size;
+ -- Number of bits in type time_t for SR0650 and before and SR0660 with
+ -- non-default configuration.
+
+ -- time_t_bits : constant := Long_Long_Integer'Size;
+ -- Number of bits in type time_t for SR0660 with default configuration.
+
----------------------------------------------
-- Characteristics of types in Interfaces.C --
----------------------------------------------
diff --git a/gcc/ada/libgnat/s-rident.ads b/gcc/ada/libgnat/s-rident.ads
index 7d0a384..10d374e 100644
--- a/gcc/ada/libgnat/s-rident.ads
+++ b/gcc/ada/libgnat/s-rident.ads
@@ -103,6 +103,7 @@ package System.Rident is
No_Direct_Boolean_Operators, -- GNAT
No_Dispatch, -- (RM H.4(19))
No_Dispatching_Calls, -- GNAT
+ No_Dynamic_Accessibility_Checks, -- GNAT
No_Dynamic_Attachment, -- Ada 2012 (RM E.7(10/3))
No_Dynamic_CPU_Assignment, -- Ada 202x (RM D.7(10/3))
No_Dynamic_Priorities, -- (RM D.9(9))
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index f7f166c..6e74e90 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -2364,7 +2364,7 @@ package body Make is
Osint.Full_Source_Name
(Source.File,
Full_File => Full_Source_File,
- Attr => Source_File_Attr'Access);
+ Attr => Source_File_Attr'Unchecked_Access);
Lib_File := Osint.Lib_File_Name (Source.File, Source.Index);
@@ -2392,7 +2392,7 @@ package body Make is
Get_Name_String (Full_Lib_File);
Name_Buffer (Name_Len + 1) := ASCII.NUL;
Read_Only := not Is_Writable_File
- (Name_Buffer'Address, Lib_File_Attr'Access);
+ (Name_Buffer'Address, Lib_File_Attr'Unchecked_Access);
else
Read_Only := False;
end if;
@@ -2460,7 +2460,7 @@ package body Make is
The_Args => Args,
Lib_File => Lib_File,
Full_Lib_File => Full_Lib_File,
- Lib_File_Attr => Lib_File_Attr'Access,
+ Lib_File_Attr => Lib_File_Attr'Unchecked_Access,
Read_Only => Read_Only,
ALI => ALI,
O_File => Obj_File,
@@ -2630,7 +2630,8 @@ package body Make is
Text :=
Read_Library_Info_From_Full
- (Data.Full_Lib_File, Data.Lib_File_Attr'Access);
+ (Data.Full_Lib_File,
+ Data.Lib_File_Attr'Unchecked_Access);
-- Restore Check_Object_Consistency to its initial value
diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
index d47eaa5..4ee6aa8 100644
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -1915,7 +1915,8 @@ package body Osint is
begin
if Opt.Look_In_Primary_Dir then
Locate_File
- (N, Source, Primary_Directory, File_Name, File, Attr'Access);
+ (N, Source, Primary_Directory, File_Name, File,
+ Attr'Unchecked_Access);
if File /= No_File and then T = File_Stamp (N) then
return File;
@@ -1925,7 +1926,7 @@ package body Osint is
Last_Dir := Src_Search_Directories.Last;
for D in Primary_Directory + 1 .. Last_Dir loop
- Locate_File (N, Source, D, File_Name, File, Attr'Access);
+ Locate_File (N, Source, D, File_Name, File, Attr'Unchecked_Access);
if File /= No_File and then T = File_Stamp (File) then
return File;
@@ -2191,8 +2192,7 @@ package body Osint is
GNAT_Time : Time_Stamp_Type;
type Underlying_OS_Time is
- range -(2 ** (Standard'Address_Size - Integer'(1))) ..
- +(2 ** (Standard'Address_Size - Integer'(1)) - 1);
+ range -(2 ** 63) .. +(2 ** 63 - 1);
-- Underlying_OS_Time is a redeclaration of OS_Time to allow integer
-- manipulation. Remove this in favor of To_Ada/To_C once newer
-- GNAT releases are available with these functions.
diff --git a/gcc/ada/par-ch10.adb b/gcc/ada/par-ch10.adb
index e140626..f02934a 100644
--- a/gcc/ada/par-ch10.adb
+++ b/gcc/ada/par-ch10.adb
@@ -555,7 +555,7 @@ package body Ch10 is
| N_Generic_Function_Renaming_Declaration
| N_Generic_Package_Renaming_Declaration
| N_Generic_Procedure_Renaming_Declaration
- or else Nkind (Unit_Node) in N_Package_Body
+ | N_Package_Body
| N_Package_Instantiation
| N_Package_Renaming_Declaration
| N_Package_Specification
@@ -1162,24 +1162,22 @@ package body Ch10 is
Loc : Source_Ptr;
SR_Present : Boolean)
is
- Unum : constant Unit_Number_Type := Get_Cunit_Unit_Number (Cunit);
- Sind : constant Source_File_Index := Source_Index (Unum);
- Unam : constant Unit_Name_Type := Unit_Name (Unum);
+ Unum : constant Unit_Number_Type := Get_Cunit_Unit_Number (Cunit);
+ Sind : constant Source_File_Index := Source_Index (Unum);
+ Unam : constant Unit_Name_Type := Unit_Name (Unum);
begin
- if List_Units then
- Write_Str ("Unit ");
- Write_Unit_Name (Unit_Name (Unum));
- Unit_Location (Sind, Loc);
+ Write_Str ("Unit ");
+ Write_Unit_Name (Unit_Name (Unum));
+ Unit_Location (Sind, Loc);
- if SR_Present then
- Write_Str (", SR");
- end if;
-
- Write_Str (", file name ");
- Write_Name (Get_File_Name (Unam, Nkind (Unit (Cunit)) = N_Subunit));
- Write_Eol;
+ if SR_Present then
+ Write_Str (", SR");
end if;
+
+ Write_Str (", file name ");
+ Write_Name (Get_File_Name (Unam, Nkind (Unit (Cunit)) = N_Subunit));
+ Write_Eol;
end Unit_Display;
-------------------
diff --git a/gcc/ada/par-ch5.adb b/gcc/ada/par-ch5.adb
index 608ebd0..1e55181 100644
--- a/gcc/ada/par-ch5.adb
+++ b/gcc/ada/par-ch5.adb
@@ -1741,7 +1741,15 @@ package body Ch5 is
if Token = Tok_Colon then
Scan; -- past :
- Set_Subtype_Indication (Node1, P_Subtype_Indication);
+
+ if Token = Tok_Access then
+ Error_Msg_Ada_2022_Feature
+ ("access definition in loop parameter", Token_Ptr);
+ Set_Subtype_Indication (Node1, P_Access_Definition (False));
+
+ else
+ Set_Subtype_Indication (Node1, P_Subtype_Indication);
+ end if;
end if;
if Token = Tok_Of then
@@ -1761,7 +1769,7 @@ package body Ch5 is
Set_Of_Present (Node1);
Error_Msg_N
("subtype indication is only legal on an element iterator",
- Subtype_Indication (Node1));
+ Subtype_Indication (Node1));
else
return Error;
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index 45a4214..be85d09 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -201,6 +201,28 @@ package body Ch6 is
-- Error recovery: cannot raise Error_Resync
function P_Subprogram (Pf_Flags : Pf_Rec) return Node_Id is
+
+ function Contains_Import_Aspect (Aspects : List_Id) return Boolean;
+ -- Return True if Aspects contains an Import aspect.
+
+ ----------------------------
+ -- Contains_Import_Aspect --
+ ----------------------------
+
+ function Contains_Import_Aspect (Aspects : List_Id) return Boolean is
+ Aspect : Node_Id := First (Aspects);
+ begin
+ while Present (Aspect) loop
+ if Chars (Identifier (Aspect)) = Name_Import then
+ return True;
+ end if;
+
+ Next (Aspect);
+ end loop;
+
+ return False;
+ end Contains_Import_Aspect;
+
Specification_Node : Node_Id;
Name_Node : Node_Id;
Aspects : List_Id;
@@ -982,10 +1004,12 @@ package body Ch6 is
if Pf_Flags.Pbod
-- Disconnect this processing if we have scanned a null procedure
- -- because in this case the spec is complete anyway with no body.
+ -- or an Import aspect because in this case the spec is complete
+ -- anyway with no body.
and then (Nkind (Specification_Node) /= N_Procedure_Specification
or else not Null_Present (Specification_Node))
+ and then not Contains_Import_Aspect (Aspects)
then
SIS_Labl := Scopes (Scope.Last).Labl;
SIS_Sloc := Scopes (Scope.Last).Sloc;
@@ -1874,43 +1898,38 @@ package body Ch6 is
function P_Return_Statement return Node_Id is
-- The caller has checked that the initial token is RETURN
- type Return_Kind is (Simple_Return, Extended_Return, Return_When);
-
- function Get_Return_Kind return Return_Kind;
+ function Is_Extended return Boolean;
-- Scan state is just after RETURN (and is left that way). Determine
-- whether this is a simple or extended return statement by looking
-- ahead for "identifier :", which implies extended.
- ---------------------
- -- Get_Return_Kind --
- ---------------------
+ -----------------
+ -- Is_Extended --
+ -----------------
- function Get_Return_Kind return Return_Kind is
- Scan_State : Saved_Scan_State;
- Result : Return_Kind := Simple_Return;
+ function Is_Extended return Boolean is
+ Scan_State : Saved_Scan_State;
+ Is_Extended : Boolean := False;
begin
+
if Token = Tok_Identifier then
Save_Scan_State (Scan_State); -- at identifier
Scan; -- past identifier
if Token = Tok_Colon then
- Result := Extended_Return; -- It's an extended_return_statement
- elsif Token = Tok_When then
- Error_Msg_GNAT_Extension ("return when statement");
-
- Result := Return_When;
+ Is_Extended := True;
end if;
Restore_Scan_State (Scan_State); -- to identifier
end if;
- return Result;
- end Get_Return_Kind;
+ return Is_Extended;
+ end Is_Extended;
Ret_Sloc : constant Source_Ptr := Token_Ptr;
Ret_Strt : constant Column_Number := Start_Column;
- Ret_Node : Node_Id := New_Node (N_Simple_Return_Statement, Ret_Sloc);
+ Ret_Node : Node_Id;
Decl : Node_Id;
-- Start of processing for P_Return_Statement
@@ -1923,75 +1942,73 @@ package body Ch6 is
if Token = Tok_Semicolon then
Scan; -- past ;
+ Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
-- Nontrivial case
else
- -- Simple_return_statement with expression
-
- -- We avoid trying to scan an expression if we are at an
- -- expression terminator since in that case the best error
- -- message is probably that we have a missing semicolon.
+ -- Extended_return_statement (Ada 2005 only -- AI-318):
- case Get_Return_Kind is
- -- Return_when_statement (Experimental only)
+ if Is_Extended then
+ Error_Msg_Ada_2005_Extension ("extended return statement");
- when Return_When =>
- Ret_Node := New_Node (N_Return_When_Statement, Ret_Sloc);
+ Ret_Node := New_Node (N_Extended_Return_Statement, Ret_Sloc);
+ Decl := P_Return_Object_Declaration;
+ Set_Return_Object_Declarations (Ret_Node, New_List (Decl));
- if Token not in Token_Class_Eterm then
- Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
- end if;
-
- if Token = Tok_When and then not Missing_Semicolon_On_When then
- Scan; -- past WHEN
- Set_Condition (Ret_Node, P_Condition);
-
- -- Allow IF instead of WHEN, giving error message
+ if Token = Tok_With then
+ P_Aspect_Specifications (Decl, False);
+ end if;
- elsif Token = Tok_If then
- T_When;
- Scan; -- past IF used in place of WHEN
- Set_Condition (Ret_Node, P_Expression_No_Right_Paren);
- end if;
+ if Token = Tok_Do then
+ Push_Scope_Stack;
+ Scopes (Scope.Last).Ecol := Ret_Strt;
+ Scopes (Scope.Last).Etyp := E_Return;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Sloc := Ret_Sloc;
+ Scan; -- past DO
+ Set_Handled_Statement_Sequence
+ (Ret_Node, P_Handled_Sequence_Of_Statements);
+ End_Statements;
+
+ -- Do we need to handle Error_Resync here???
+ end if;
- -- Simple_return_statement
+ -- Simple_return_statement or Return_when_Statement
+ -- with expression.
- when Simple_Return =>
- Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
+ -- We avoid trying to scan an expression if we are at an
+ -- expression terminator since in that case the best error
+ -- message is probably that we have a missing semicolon.
- if Token not in Token_Class_Eterm then
- Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
- end if;
+ else
+ Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
- -- Extended_return_statement (Ada 2005 only -- AI-318):
+ if Token not in Token_Class_Eterm then
+ Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
+ end if;
- when Extended_Return =>
- Error_Msg_Ada_2005_Extension ("extended return statement");
+ -- When the next token is WHEN or IF we know that we are looking
+ -- at a Return_when_statement
- Ret_Node := New_Node (N_Extended_Return_Statement, Ret_Sloc);
- Decl := P_Return_Object_Declaration;
- Set_Return_Object_Declarations (Ret_Node, New_List (Decl));
+ if Token = Tok_When and then not Missing_Semicolon_On_When then
+ Error_Msg_GNAT_Extension ("return when statement");
+ Mutate_Nkind (Ret_Node, N_Return_When_Statement);
- if Token = Tok_With then
- P_Aspect_Specifications (Decl, False);
- end if;
+ Scan; -- past WHEN
+ Set_Condition (Ret_Node, P_Condition);
- if Token = Tok_Do then
- Push_Scope_Stack;
- Scopes (Scope.Last).Ecol := Ret_Strt;
- Scopes (Scope.Last).Etyp := E_Return;
- Scopes (Scope.Last).Labl := Error;
- Scopes (Scope.Last).Sloc := Ret_Sloc;
+ -- Allow IF instead of WHEN, giving error message
- Scan; -- past DO
- Set_Handled_Statement_Sequence
- (Ret_Node, P_Handled_Sequence_Of_Statements);
- End_Statements;
+ elsif Token = Tok_If then
+ Error_Msg_GNAT_Extension ("return when statement");
+ Mutate_Nkind (Ret_Node, N_Return_When_Statement);
- -- Do we need to handle Error_Resync here???
- end if;
- end case;
+ T_When;
+ Scan; -- past IF used in place of WHEN
+ Set_Condition (Ret_Node, P_Condition);
+ end if;
+ end if;
TF_Semicolon;
end if;
diff --git a/gcc/ada/par-load.adb b/gcc/ada/par-load.adb
index 05e9f9e..dcba6d5 100644
--- a/gcc/ada/par-load.adb
+++ b/gcc/ada/par-load.adb
@@ -129,8 +129,8 @@ begin
Save_Style_Check_Options (Save_Style_Checks);
Save_Style_Check := Opt.Style_Check;
- -- If main unit, set Main_Unit_Entity (this will get overwritten if
- -- the main unit has a separate spec, that happens later on in Load)
+ -- If main unit, set Main_Unit_Entity (this will get overwritten if the
+ -- main unit has a separate spec, that happens later on in Load).
if Cur_Unum = Main_Unit then
Main_Unit_Entity := Cunit_Entity (Main_Unit);
@@ -182,14 +182,8 @@ begin
-- Check for predefined file case
if Name_Len > 1
+ and then Name_Buffer (1) in 'a' | 's' | 'i' | 'g'
and then Name_Buffer (2) = '-'
- and then (Name_Buffer (1) = 'a'
- or else
- Name_Buffer (1) = 's'
- or else
- Name_Buffer (1) = 'i'
- or else
- Name_Buffer (1) = 'g')
then
declare
Expect_Name : constant Unit_Name_Type := Expected_Unit (Cur_Unum);
@@ -240,17 +234,15 @@ begin
Error_Msg ("\\found unit $!", Loc);
end if;
- -- In both cases, remove the unit if it is the last unit (which it
- -- normally (always?) will be) so that it is out of the way later.
+ -- In both cases, flag the fatal error and give up
- Remove_Unit (Cur_Unum);
+ Set_Fatal_Error (Cur_Unum, Error_Detected);
+ return;
end if;
-- If current unit is a body, load its corresponding spec
- if Nkind (Unit (Curunit)) = N_Package_Body
- or else Nkind (Unit (Curunit)) = N_Subprogram_Body
- then
+ if Nkind (Unit (Curunit)) in N_Package_Body | N_Subprogram_Body then
Spec_Name := Get_Spec_Name (Unit_Name (Cur_Unum));
Unum :=
Load_Unit
@@ -274,6 +266,12 @@ begin
-- and this is also where we generate the SCO's for this spec.
if Cur_Unum = Main_Unit then
+
+ -- We generate code for the main unit body, so we need to generate
+ -- code for its spec too.
+
+ Set_Generate_Code (Unum, True);
+
Main_Unit_Entity := Cunit_Entity (Unum);
if Generate_SCO then
@@ -304,11 +302,11 @@ begin
-- If current unit is a child unit spec, load its parent. If the child unit
-- is loaded through a limited with, the parent must be as well.
- elsif Nkind (Unit (Curunit)) = N_Package_Declaration
- or else Nkind (Unit (Curunit)) = N_Subprogram_Declaration
- or else Nkind (Unit (Curunit)) in N_Generic_Declaration
- or else Nkind (Unit (Curunit)) in N_Generic_Instantiation
- or else Nkind (Unit (Curunit)) in N_Renaming_Declaration
+ elsif Nkind (Unit (Curunit)) in N_Package_Declaration
+ | N_Subprogram_Declaration
+ | N_Generic_Declaration
+ | N_Generic_Instantiation
+ | N_Renaming_Declaration
then
-- Turn style checks off for parent unit
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index d701c2c..06c7d87 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -1389,6 +1389,7 @@ begin
| Pragma_Finalize_Storage_Only
| Pragma_Ghost
| Pragma_Global
+ | Pragma_GNAT_Annotate
| Pragma_Ident
| Pragma_Implementation_Defined
| Pragma_Implemented
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 649d2a0..312c411 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -1650,14 +1650,12 @@ begin
Uname : constant String :=
Get_Name_String
(Unit_Name (Current_Source_Unit));
- Name : String (1 .. Uname'Length - 2);
-
- begin
+ Name : String renames
+ Uname (Uname'First .. Uname'Last - 2);
-- Because Unit_Name includes "%s"/"%b", we need to strip
-- the last two characters to get the real unit name.
- Name := Uname (Uname'First .. Uname'Last - 2);
-
+ begin
if Name = "ada" or else
Name = "interfaces" or else
Name = "system"
diff --git a/gcc/ada/repinfo-input.adb b/gcc/ada/repinfo-input.adb
index 106c43c..5d85040 100644
--- a/gcc/ada/repinfo-input.adb
+++ b/gcc/ada/repinfo-input.adb
@@ -38,7 +38,7 @@ package body Repinfo.Input is
-- Value for Storage_Unit
type JSON_Entity_Kind is (JE_Record_Type, JE_Array_Type, JE_Other);
- -- Kind of an entiy
+ -- Kind of an entity
type JSON_Entity_Node (Kind : JSON_Entity_Kind := JE_Other) is record
Esize : Node_Ref_Or_Val;
@@ -1219,7 +1219,7 @@ package body Repinfo.Input is
Var : JSON_Variant_Node;
begin
- -- Read a non-empty array of components
+ -- Read a nonempty array of components
Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);
diff --git a/gcc/ada/repinfo.adb b/gcc/ada/repinfo.adb
index 137c867..25b5237 100644
--- a/gcc/ada/repinfo.adb
+++ b/gcc/ada/repinfo.adb
@@ -963,10 +963,15 @@ package body Repinfo is
procedure List_Structural_Record_Layout
(Ent : Entity_Id;
- Outer_Ent : Entity_Id;
+ Ext_Ent : Entity_Id;
+ Ext_Level : Nat := 0;
Variant : Node_Id := Empty;
Indent : Natural := 0);
- -- Internal recursive procedure to display the structural layout
+ -- Internal recursive procedure to display the structural layout.
+ -- If Ext_Ent is not equal to Ent, it is an extension of Ent and
+ -- Ext_Level is the number of successive extensions between them.
+ -- If Variant is present, it's for a variant in the variant part
+ -- instead of the common part of Ent. Indent is the indentation.
Incomplete_Layout : exception;
-- Exception raised if the layout is incomplete in -gnatc mode
@@ -1031,7 +1036,7 @@ package body Repinfo is
-- whose position is not specified have starting normalized
-- bit position of zero.
- if Unknown_Normalized_First_Bit (Comp)
+ if not Known_Normalized_First_Bit (Comp)
and then not Is_Packed (Ent)
then
Set_Normalized_First_Bit (Comp, Uint_0);
@@ -1044,7 +1049,7 @@ package body Repinfo is
-- Complete annotation in case not done
- if Unknown_Normalized_First_Bit (Comp) then
+ if not Known_Normalized_First_Bit (Comp) then
Set_Normalized_Position (Comp, Npos);
Set_Normalized_First_Bit (Comp, Fbit);
end if;
@@ -1202,7 +1207,7 @@ package body Repinfo is
-- No_Uint, not Uint_0. Really everyone should use No_Uint???
elsif List_Representation_Info < 3
- or else (Esize (Ent) /= Uint_0 and then Unknown_Esize (Ent))
+ or else (Esize (Ent) /= Uint_0 and then not Known_Esize (Ent))
then
Write_Unknown_Val;
@@ -1319,7 +1324,12 @@ package body Repinfo is
end if;
end if;
- List_Component_Layout (Comp,
+ -- The Parent_Subtype in an extension is not back-annotated
+
+ List_Component_Layout (
+ (if Known_Normalized_Position (Comp)
+ then Comp
+ else Original_Record_Component (Comp)),
Starting_Position, Starting_First_Bit, Prefix);
end;
@@ -1334,15 +1344,16 @@ package body Repinfo is
procedure List_Structural_Record_Layout
(Ent : Entity_Id;
- Outer_Ent : Entity_Id;
+ Ext_Ent : Entity_Id;
+ Ext_Level : Nat := 0;
Variant : Node_Id := Empty;
Indent : Natural := 0)
is
function Derived_Discriminant (Disc : Entity_Id) return Entity_Id;
- -- This function assumes that Outer_Ent is an extension of Ent.
+ -- This function assumes that Ext_Ent is an extension of Ent.
-- Disc is a discriminant of Ent that does not itself constrain a
-- discriminant of the parent type of Ent. Return the discriminant
- -- of Outer_Ent that ultimately constrains Disc, if any.
+ -- of Ext_Ent that ultimately constrains Disc, if any.
----------------------------
-- Derived_Discriminant --
@@ -1353,7 +1364,7 @@ package body Repinfo is
Derived_Disc : Entity_Id;
begin
- Derived_Disc := First_Discriminant (Outer_Ent);
+ Derived_Disc := First_Discriminant (Ext_Ent);
-- Loop over the discriminants of the extension
@@ -1380,7 +1391,7 @@ package body Repinfo is
Next_Discriminant (Derived_Disc);
end loop;
- -- Disc is not constrained by a discriminant of Outer_Ent
+ -- Disc is not constrained by a discriminant of Ext_Ent
return Empty;
end Derived_Discriminant;
@@ -1432,12 +1443,21 @@ package body Repinfo is
pragma Assert (Present (Parent_Type));
end if;
- Parent_Type := Base_Type (Parent_Type);
- if not In_Extended_Main_Source_Unit (Parent_Type) then
- raise Not_In_Extended_Main;
+ -- Do not list variants if one of them has been selected
+
+ if Has_Static_Discriminants (Parent_Type) then
+ List_Record_Layout (Parent_Type);
+
+ else
+ Parent_Type := Base_Type (Parent_Type);
+ if not In_Extended_Main_Source_Unit (Parent_Type) then
+ raise Not_In_Extended_Main;
+ end if;
+
+ List_Structural_Record_Layout
+ (Parent_Type, Ext_Ent, Ext_Level + 1);
end if;
- List_Structural_Record_Layout (Parent_Type, Outer_Ent);
First := False;
if Present (Record_Extension_Part (Definition)) then
@@ -1467,7 +1487,7 @@ package body Repinfo is
-- If this is the parent type of an extension, retrieve
-- the derived discriminant from the extension, if any.
- if Ent /= Outer_Ent then
+ if Ent /= Ext_Ent then
Listed_Disc := Derived_Discriminant (Disc);
if No (Listed_Disc) then
@@ -1544,7 +1564,11 @@ package body Repinfo is
Spaces (Indent);
Write_Line (" ],");
Spaces (Indent);
- Write_Str (" ""variant"" : [");
+ Write_Str (" """);
+ for J in 1 .. Ext_Level loop
+ Write_Str ("parent_");
+ end loop;
+ Write_Str ("variant"" : [");
-- Otherwise we recurse on each variant
@@ -1567,7 +1591,8 @@ package body Repinfo is
Spaces (Indent);
Write_Str (" ""record"": [");
- List_Structural_Record_Layout (Ent, Outer_Ent, Var, Indent + 4);
+ List_Structural_Record_Layout
+ (Ent, Ext_Ent, Ext_Level, Var, Indent + 4);
Write_Eol;
Spaces (Indent);
diff --git a/gcc/ada/repinfo.ads b/gcc/ada/repinfo.ads
index 45eb0ab..606bba4 100644
--- a/gcc/ada/repinfo.ads
+++ b/gcc/ada/repinfo.ads
@@ -189,7 +189,7 @@ package Repinfo is
-- "name" : string
-- "location" : string
-- "record" : array of components
- -- "variant" : array of variants
+ -- "[parent_]*variant" : array of variants
-- "formal" : array of formal parameters
-- "mechanism" : string
-- "Size" : numerical expression
@@ -209,8 +209,9 @@ package Repinfo is
-- fully qualified Ada name. The value of "location" is the expanded
-- chain of instantiation locations that contains the entity.
-- "record" is present for every record type and its value is the list of
- -- components. "variant" is present only if the record type has a variant
- -- part and its value is the list of variants.
+ -- components. "[parent_]*variant" is present only if the record type, or
+ -- one of its ancestors (parent, grand-parent, etc) if it's an extension,
+ -- has a variant part and its value is the list of variants.
-- "formal" is present for every subprogram and entry, and its value is
-- the list of formal parameters. "mechanism" is present for functions
-- only and its value is the return mechanim.
diff --git a/gcc/ada/restrict.adb b/gcc/ada/restrict.adb
index 3592230..d97a42e 100644
--- a/gcc/ada/restrict.adb
+++ b/gcc/ada/restrict.adb
@@ -396,10 +396,9 @@ package body Restrict is
N : Node_Id;
V : Uint := Uint_Minus_1)
is
- Msg_Issued : Boolean;
- pragma Unreferenced (Msg_Issued);
+ Ignore_Msg_Issued : Boolean;
begin
- Check_Restriction (Msg_Issued, R, N, V);
+ Check_Restriction (Ignore_Msg_Issued, R, N, V);
end Check_Restriction;
procedure Check_Restriction
@@ -924,6 +923,21 @@ package body Restrict is
or else Targparm.Restrictions_On_Target.Set (No_Tasking);
end Global_No_Tasking;
+ ---------------------------------------------
+ -- No_Dynamic_Accessibility_Checks_Enabled --
+ ---------------------------------------------
+
+ function No_Dynamic_Accessibility_Checks_Enabled
+ (N : Node_Id) return Boolean
+ is
+ pragma Unreferenced (N);
+ -- N is currently unreferenced but present for debugging purposes and
+ -- potential future use.
+
+ begin
+ return Restrictions.Set (No_Dynamic_Accessibility_Checks);
+ end No_Dynamic_Accessibility_Checks_Enabled;
+
-------------------------------
-- No_Exception_Handlers_Set --
-------------------------------
diff --git a/gcc/ada/restrict.ads b/gcc/ada/restrict.ads
index 806195e..eec85c2 100644
--- a/gcc/ada/restrict.ads
+++ b/gcc/ada/restrict.ads
@@ -114,6 +114,7 @@ package Restrict is
No_Default_Initialization => True,
No_Direct_Boolean_Operators => True,
No_Dispatching_Calls => True,
+ No_Dynamic_Accessibility_Checks => True,
No_Dynamic_Attachment => True,
No_Elaboration_Code => True,
No_Enumeration_Maps => True,
@@ -377,6 +378,15 @@ package Restrict is
-- pragma Restrictions_Warning, or attribute Restriction_Set. Returns
-- True if N has the proper form for an entity name, False otherwise.
+ function No_Dynamic_Accessibility_Checks_Enabled
+ (N : Node_Id) return Boolean;
+ -- Test to see if the current restrictions settings specify that
+ -- No_Dynamic_Accessibility_Checks is activated.
+
+ -- N is currently unused, but is reserved for future use and debugging
+ -- purposes to provide more context on a node for which an accessibility
+ -- check is being performed or generated (e.g. is N in a predefined unit).
+
function No_Exception_Handlers_Set return Boolean;
-- Test to see if current restrictions settings specify that no exception
-- handlers are present. This function is called by Gigi when it needs to
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
index 391c7e9..83a63c8 100644
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -147,6 +147,19 @@ static void skip_quoted_string (const WCHAR **current_in,
}
ci++;
}
+
+ /* Handle the case in which a nul character was found instead of a closing
+ double quote. In that case consider all the backslashes as literal
+ characters. */
+ if (*ci == '\0')
+ {
+ for (int i=0; i<qbs_count; i++)
+ {
+ *co='\\';
+ co++;
+ }
+ }
+
*current_in = ci;
*current_out = co;
}
@@ -205,7 +218,10 @@ static void skip_argument (const WCHAR **current_in,
bs_count = 0;
*co = *ci; co++;
}
- ci++;
+ if (*ci != '\0')
+ {
+ ci++;
+ }
}
for (int i=0; i<bs_count; i++)
diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb
index 6fe6f85..5a89076 100644
--- a/gcc/ada/rtsfind.adb
+++ b/gcc/ada/rtsfind.adb
@@ -602,6 +602,10 @@ package body Rtsfind is
subtype System_Descendant is RTU_Id
range System_Address_Image .. System_Tasking_Stages;
+ subtype System_Atomic_Operations_Descendant is System_Descendant
+ range System_Atomic_Operations_Test_And_Set ..
+ System_Atomic_Operations_Test_And_Set;
+
subtype System_Dim_Descendant is System_Descendant
range System_Dim_Float_IO .. System_Dim_Integer_IO;
@@ -689,6 +693,10 @@ package body Rtsfind is
elsif U_Id in System_Descendant then
Name_Buffer (7) := '.';
+ if U_Id in System_Atomic_Operations_Descendant then
+ Name_Buffer (25) := '.';
+ end if;
+
if U_Id in System_Dim_Descendant then
Name_Buffer (11) := '.';
end if;
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index ad84e9e..99f870a 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -195,6 +195,7 @@ package Rtsfind is
System_Arith_128,
System_AST_Handling,
System_Assertions,
+ System_Atomic_Operations,
System_Atomic_Primitives,
System_Aux_DEC,
System_Bignums,
@@ -468,6 +469,10 @@ package Rtsfind is
System_WWd_Enum,
System_WWd_Wchar,
+ -- Children of System.Atomic_Operations
+
+ System_Atomic_Operations_Test_And_Set,
+
-- Children of System.Dim
System_Dim_Float_IO,
@@ -708,6 +713,7 @@ package Rtsfind is
RE_TK_Tagged, -- Ada.Tags
RE_TK_Task, -- Ada.Tags
RE_Unregister_Tag, -- Ada.Tags
+ RE_Wide_Wide_Expanded_Name, -- Ada.Tags
RE_Set_Specific_Handler, -- Ada.Task_Termination
RE_Specific_Handler, -- Ada.Task_Termination
@@ -799,6 +805,9 @@ package Rtsfind is
RE_Uint32, -- System.Atomic_Primitives
RE_Uint64, -- System.Atomic_Primitives
+ RE_Test_And_Set_Flag, -- System.Atomic_Operations.Test_And_Set
+ RE_Atomic_Test_And_Set, -- System.Atomic_Operations.Test_And_Set
+
RE_AST_Handler, -- System.Aux_DEC
RE_Import_Address, -- System.Aux_DEC
RE_Import_Value, -- System.Aux_DEC
@@ -2389,6 +2398,7 @@ package Rtsfind is
RE_TK_Tagged => Ada_Tags,
RE_TK_Task => Ada_Tags,
RE_Unregister_Tag => Ada_Tags,
+ RE_Wide_Wide_Expanded_Name => Ada_Tags,
RE_Set_Specific_Handler => Ada_Task_Termination,
RE_Specific_Handler => Ada_Task_Termination,
@@ -2480,6 +2490,9 @@ package Rtsfind is
RE_Uint32 => System_Atomic_Primitives,
RE_Uint64 => System_Atomic_Primitives,
+ RE_Test_And_Set_Flag => System_Atomic_Operations_Test_And_Set,
+ RE_Atomic_Test_And_Set => System_Atomic_Operations_Test_And_Set,
+
RE_AST_Handler => System_Aux_DEC,
RE_Import_Address => System_Aux_DEC,
RE_Import_Value => System_Aux_DEC,
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index d42e663..54fa2f1 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -1463,14 +1463,8 @@ CND(MSG_PEEK, "Peek at incoming data")
CND(MSG_EOR, "Send end of record")
#ifndef MSG_WAITALL
-#ifdef __MINWGW32__
-/* The value of MSG_WAITALL is 8. Nevertheless winsock.h doesn't
- define it, but it is still usable as we link to winsock2 API. */
-# define MSG_WAITALL (1 << 3)
-#else
# define MSG_WAITALL -1
#endif
-#endif
CND(MSG_WAITALL, "Wait for full reception")
#ifndef MSG_NOSIGNAL
@@ -1502,18 +1496,36 @@ CNS(MSG_Forced_Flags, "")
CND(TCP_NODELAY, "Do not coalesce packets")
#ifndef TCP_KEEPCNT
+#ifdef __MINGW32__
+/* Windows headers can be too old to have all available constants.
+ * We know this one. */
+# define TCP_KEEPCNT 16
+#else
# define TCP_KEEPCNT -1
#endif
+#endif
CND(TCP_KEEPCNT, "Maximum number of keepalive probes")
#ifndef TCP_KEEPIDLE
+#ifdef __MINGW32__
+/* Windows headers can be too old to have all available constants.
+ * We know this one. */
+# define TCP_KEEPIDLE 3
+#else
# define TCP_KEEPIDLE -1
#endif
+#endif
CND(TCP_KEEPIDLE, "Idle time before TCP starts sending keepalive probes")
#ifndef TCP_KEEPINTVL
+#ifdef __MINGW32__
+/* Windows headers can be too old to have all available constants.
+ * We know this one. */
+# define TCP_KEEPINTVL 17
+#else
# define TCP_KEEPINTVL -1
#endif
+#endif
CND(TCP_KEEPINTVL, "Time between individual keepalive probes")
#ifndef SO_REUSEADDR
@@ -1677,8 +1689,14 @@ CND(IPV6_DSTOPTS, "Set the destination options delivery")
CND(IPV6_HOPOPTS, "Set the hop options delivery")
#ifndef IPV6_FLOWINFO
+#ifdef __linux__
+/* The IPV6_FLOWINFO is defined in linux/in6.h, but we can't include it because
+ * of conflicts with other headers. */
+# define IPV6_FLOWINFO 11
+#else
# define IPV6_FLOWINFO -1
#endif
+#endif
CND(IPV6_FLOWINFO, "Set the flow ID delivery")
#ifndef IPV6_HOPLIMIT
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index 66b1105..bf1307c 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -230,16 +230,16 @@ package body Scng is
-- Initialize scan control variables
- Current_Source_File := Index;
- Source := Source_Text (Current_Source_File);
- Scan_Ptr := Source_First (Current_Source_File);
- Token := No_Token;
- Token_Ptr := Scan_Ptr;
- Current_Line_Start := Scan_Ptr;
- Token_Node := Empty;
- Token_Name := No_Name;
- Start_Column := Set_Start_Column;
- First_Non_Blank_Location := Scan_Ptr;
+ Current_Source_File := Index;
+ Source := Source_Text (Current_Source_File);
+ Scan_Ptr := Source_First (Current_Source_File);
+ Token := No_Token;
+ Token_Ptr := Scan_Ptr;
+ Current_Line_Start := Scan_Ptr;
+ Token_Node := Empty;
+ Token_Name := No_Name;
+ Start_Column := Set_Start_Column;
+ First_Non_Blank_Location := Scan_Ptr;
Initialize_Checksum;
Wide_Char_Byte_Count := 0;
diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads
index a56ce937..2fdccf7 100644
--- a/gcc/ada/sem.ads
+++ b/gcc/ada/sem.ads
@@ -533,7 +533,7 @@ package Sem is
-- See Sem_Ch10 (Install_Parents, Remove_Parents).
Node_To_Be_Wrapped : Node_Id;
- -- Only used in transient scopes. Records the node which will be wrapped
+ -- Only used in transient scopes. Records the node that will be wrapped
-- by the transient block.
Actions_To_Be_Wrapped : Scope_Actions;
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index d189ab7..9ad9629 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -5028,12 +5028,19 @@ package body Sem_Aggr is
Prepend_Elmt (Parent_Typ, To => Parent_Typ_List);
Parent_Typ := Etype (Parent_Typ);
+ -- Check whether a private parent requires the use of
+ -- an extension aggregate. This test does not apply in
+ -- an instantiation: if the generic unit is legal so is
+ -- the instance.
+
if Nkind (Parent (Base_Type (Parent_Typ))) =
N_Private_Type_Declaration
or else Nkind (Parent (Base_Type (Parent_Typ))) =
N_Private_Extension_Declaration
then
- if Nkind (N) /= N_Extension_Aggregate then
+ if Nkind (N) /= N_Extension_Aggregate
+ and then not In_Instance
+ then
Error_Msg_NE
("type of aggregate has private ancestor&!",
N, Parent_Typ);
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index b7297e5..d1a91d8 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -11290,7 +11290,11 @@ package body Sem_Attr is
-- this kind of warning is an error in SPARK mode.
if In_Instance_Body then
- Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_Warn :=
+ SPARK_Mode /= On
+ and then
+ not No_Dynamic_Accessibility_Checks_Enabled (P);
+
Error_Msg_F
("non-local pointer cannot point to local object<<", P);
Error_Msg_F ("\Program_Error [<<", P);
@@ -11422,10 +11426,13 @@ package body Sem_Attr is
-- Check the static accessibility rule of 3.10.2(28). Note that
-- this check is not performed for the case of an anonymous
-- access type, since the access attribute is always legal
- -- in such a context.
+ -- in such a context - unless the restriction
+ -- No_Dynamic_Accessibility_Checks is active.
if Attr_Id /= Attribute_Unchecked_Access
- and then Ekind (Btyp) = E_General_Access_Type
+ and then
+ (Ekind (Btyp) = E_General_Access_Type
+ or else No_Dynamic_Accessibility_Checks_Enabled (Btyp))
-- Call Accessibility_Level directly to avoid returning zero
-- on cases where the prefix is an explicitly aliased
@@ -11492,6 +11499,25 @@ package body Sem_Attr is
Error_Msg_F ("context requires a non-protected subprogram", P);
end if;
+ -- AI12-0412: The rule in RM 6.1.1(18.2/5) disallows applying
+ -- attribute Access to a primitive of an abstract type when the
+ -- primitive has any Pre'Class or Post'Class aspects specified
+ -- with nonstatic expressions.
+
+ if Attr_Id = Attribute_Access
+ and then Ekind (Btyp) in E_Access_Subprogram_Type
+ | E_Anonymous_Access_Subprogram_Type
+ and then Is_Entity_Name (P)
+ and then Is_Dispatching_Operation (Entity (P))
+ and then
+ Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Entity (P))
+ then
+ Error_Msg_N
+ ("attribute not allowed for primitive of abstract type with "
+ & "nonstatic class-wide pre/postconditions",
+ N);
+ end if;
+
-- The context cannot be a pool-specific type, but this is a
-- legality rule, not a resolution rule, so it must be checked
-- separately, after possibly disambiguation (see AI-245).
diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb
index 36db9a7..7d08da5 100644
--- a/gcc/ada/sem_case.adb
+++ b/gcc/ada/sem_case.adb
@@ -27,6 +27,7 @@ with Atree; use Atree;
with Einfo; use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils; use Einfo.Utils;
+with Elists; use Elists;
with Errout; use Errout;
with Namet; use Namet;
with Nlists; use Nlists;
@@ -90,13 +91,18 @@ package body Sem_Case is
--
-- Bounds_Type is the type whose range must be covered by the alternatives
--
- -- Subtyp is the subtype of the expression. If its bounds are non-static
+ -- Subtyp is the subtype of the expression. If its bounds are nonstatic
-- the alternatives must cover its base type.
function Choice_Image (Value : Uint; Ctype : Entity_Id) return Name_Id;
-- Given a Pos value of enumeration type Ctype, returns the name
-- ID of an appropriate string to be used in error message output.
+ function Has_Static_Discriminant_Constraint
+ (Subtyp : Entity_Id) return Boolean;
+ -- Returns True if the given subtype is subject to a discriminant
+ -- constraint and at least one of the constraint values is nonstatic.
+
package Composite_Case_Ops is
function Scalar_Part_Count (Subtyp : Entity_Id) return Nat;
@@ -255,9 +261,9 @@ package body Sem_Case is
-- is posted at location C. Caller sets Error_Msg_Sloc for xx.
procedure Explain_Non_Static_Bound;
- -- Called when we find a non-static bound, requiring the base type to
+ -- Called when we find a nonstatic bound, requiring the base type to
-- be covered. Provides where possible a helpful explanation of why the
- -- bounds are non-static, since this is not always obvious.
+ -- bounds are nonstatic, since this is not always obvious.
function Lt_Choice (C1, C2 : Natural) return Boolean;
-- Comparison routine for comparing Choice_Table entries. Use the lower
@@ -734,7 +740,7 @@ package body Sem_Case is
("bounds of & are not static, "
& "alternatives must cover base type!", Expr, Expr);
- -- If this is a case statement, the expression may be non-static
+ -- If this is a case statement, the expression may be nonstatic
-- or else the subtype may be at fault.
elsif Is_Entity_Name (Expr) then
@@ -1124,14 +1130,14 @@ package body Sem_Case is
return Static_Array_Length (Subtyp)
* Scalar_Part_Count (Component_Type (Subtyp));
elsif Is_Record_Type (Subtyp) then
- pragma Assert (not Has_Discriminants (Subtyp));
declare
Result : Nat := 0;
- Comp : Entity_Id := First_Component (Subtyp);
+ Comp : Entity_Id := First_Component_Or_Discriminant
+ (Base_Type (Subtyp));
begin
while Present (Comp) loop
Result := Result + Scalar_Part_Count (Etype (Comp));
- Next_Component (Comp);
+ Next_Component_Or_Discriminant (Comp);
end loop;
return Result;
end;
@@ -1218,15 +1224,47 @@ package body Sem_Case is
Traverse_Discrete_Parts (Component_Type (Subtyp));
end loop;
elsif Is_Record_Type (Subtyp) then
- pragma Assert (not Has_Discriminants (Subtyp));
- declare
- Comp : Entity_Id := First_Component (Subtyp);
- begin
- while Present (Comp) loop
- Traverse_Discrete_Parts (Etype (Comp));
- Next_Component (Comp);
- end loop;
- end;
+ if Has_Static_Discriminant_Constraint (Subtyp) then
+
+ -- The component range for a constrained discriminant
+ -- is a single value.
+ declare
+ Dc_Elmt : Elmt_Id :=
+ First_Elmt (Discriminant_Constraint (Subtyp));
+ Dc_Value : Uint;
+ begin
+ while Present (Dc_Elmt) loop
+ Dc_Value := Expr_Value (Node (Dc_Elmt));
+ Update_Result ((Low => Dc_Value,
+ High => Dc_Value));
+
+ Next_Elmt (Dc_Elmt);
+ end loop;
+ end;
+
+ -- Generate ranges for nondiscriminant components.
+ declare
+ Comp : Entity_Id := First_Component
+ (Base_Type (Subtyp));
+ begin
+ while Present (Comp) loop
+ Traverse_Discrete_Parts (Etype (Comp));
+ Next_Component (Comp);
+ end loop;
+ end;
+ else
+ -- Generate ranges for all components
+ declare
+ Comp : Entity_Id :=
+ First_Component_Or_Discriminant
+ (Base_Type (Subtyp));
+ begin
+ while Present (Comp) loop
+ Traverse_Discrete_Parts (Etype (Comp));
+ Next_Component_Or_Discriminant (Comp);
+ end loop;
+ end;
+ end if;
else
Error_Msg_N
("case selector type having a non-discrete non-record"
@@ -1234,6 +1272,7 @@ package body Sem_Case is
Expression (Case_Statement));
end if;
end Traverse_Discrete_Parts;
+
begin
Traverse_Discrete_Parts (Etype (Expression (Case_Statement)));
pragma Assert (Done or else Serious_Errors_Detected > 0);
@@ -1338,12 +1377,23 @@ package body Sem_Case is
is
Result : Choice_Range_Info (Is_Others => False);
Ranges : Composite_Range_Info renames Result.Ranges;
- Next_Part : Part_Id := 1;
- Done : Boolean := False;
+ Next_Part : Part_Id'Base range 1 .. Part_Id'Last + 1 := 1;
+
+ procedure Traverse_Choice (Expr : Node_Id);
+ -- Traverse a legal choice expression, looking for
+ -- values/ranges of discrete parts. Call Update_Result
+ -- for each.
procedure Update_Result (Discrete_Range : Discrete_Range_Info);
-- Initialize first remaining uninitialized element of Ranges.
- -- Also set Next_Part and Done.
+ -- Also set Next_Part.
+
+ procedure Update_Result_For_Full_Coverage (Comp_Type : Entity_Id);
+ -- For each scalar part of the given component type, call
+ -- Update_Result with the full range for that scalar part.
+ -- This is used for both box components in aggregates and
+ -- for any inactive-variant components that do not appear in
+ -- a given aggregate.
-------------------
-- Update_Result --
@@ -1351,19 +1401,21 @@ package body Sem_Case is
procedure Update_Result (Discrete_Range : Discrete_Range_Info) is
begin
- pragma Assert (not Done);
Ranges (Next_Part) := Discrete_Range;
- if Next_Part = Part_Id'Last then
- Done := True;
- else
- Next_Part := Next_Part + 1;
- end if;
+ Next_Part := Next_Part + 1;
end Update_Result;
- procedure Traverse_Choice (Expr : Node_Id);
- -- Traverse a legal choice expression, looking for
- -- values/ranges of discrete parts. Call Update_Result
- -- for each.
+ -------------------------------------
+ -- Update_Result_For_Full_Coverage --
+ -------------------------------------
+
+ procedure Update_Result_For_Full_Coverage (Comp_Type : Entity_Id)
+ is
+ begin
+ for Counter in 1 .. Scalar_Part_Count (Comp_Type) loop
+ Update_Result (Component_Bounds (Next_Part));
+ end loop;
+ end Update_Result_For_Full_Coverage;
---------------------
-- Traverse_Choice --
@@ -1388,52 +1440,89 @@ package body Sem_Case is
Refresh_Binding_Info (Aggr => Expr);
declare
- Comp : Node_Id :=
+ Comp_Assoc : Node_Id :=
First (Component_Associations (Expr));
- -- Ok to assume that components are in order here?
+ -- Aggregate has been normalized (components in
+ -- order, only one component per choice, etc.).
+
+ Comp_From_Type : Node_Id :=
+ First_Component_Or_Discriminant
+ (Base_Type (Etype (Expr)));
+
+ Saved_Next_Part : constant Part_Id := Next_Part;
begin
- while Present (Comp) loop
- pragma Assert (List_Length (Choices (Comp)) = 1);
- if Box_Present (Comp) then
- declare
- Comp_Type : constant Entity_Id :=
- Etype (First (Choices (Comp)));
- begin
- if Is_Discrete_Type (Comp_Type) then
- declare
- Low : constant Node_Id :=
- Type_Low_Bound (Comp_Type);
- High : constant Node_Id :=
- Type_High_Bound (Comp_Type);
- begin
- Update_Result
- ((Low => Expr_Value (Low),
- High => Expr_Value (High)));
- end;
- else
- -- Need to recursively traverse type
- -- here, calling Update_Result for
- -- each discrete subcomponent.
+ while Present (Comp_Assoc) loop
+ pragma Assert
+ (List_Length (Choices (Comp_Assoc)) = 1);
- Error_Msg_N
- ("box values for nondiscrete pattern "
- & "subcomponents unimplemented", Comp);
+ declare
+ Comp : constant Node_Id :=
+ Entity (First (Choices (Comp_Assoc)));
+ Comp_Seen : Boolean := False;
+ begin
+ loop
+ if Original_Record_Component (Comp) =
+ Original_Record_Component (Comp_From_Type)
+ then
+ Comp_Seen := True;
+ else
+ -- We have an aggregate of a type that
+ -- has a variant part (or has a
+ -- subcomponent type that has a variant
+ -- part) and we have to deal with a
+ -- component that is present in the type
+ -- but not in the aggregate (because the
+ -- component is in an inactive variant).
+ --
+ Update_Result_For_Full_Coverage
+ (Comp_Type => Etype (Comp_From_Type));
end if;
- end;
+
+ Comp_From_Type :=
+ Next_Component_Or_Discriminant
+ (Comp_From_Type);
+
+ exit when Comp_Seen;
+ end loop;
+ end;
+
+ if Box_Present (Comp_Assoc) then
+ -- Box matches all values
+ Update_Result_For_Full_Coverage
+ (Etype (First (Choices (Comp_Assoc))));
else
- Traverse_Choice (Expression (Comp));
+ Traverse_Choice (Expression (Comp_Assoc));
end if;
- if Binding_Chars (Comp) /= No_Name
+ if Binding_Chars (Comp_Assoc) /= No_Name
then
Case_Bindings.Note_Binding
- (Comp_Assoc => Comp,
+ (Comp_Assoc => Comp_Assoc,
Choice => Choice,
Alt => Alt);
end if;
- Next (Comp);
+ Next (Comp_Assoc);
end loop;
+
+ while Present (Comp_From_Type) loop
+ -- Deal with any trailing inactive-variant
+ -- components.
+ --
+ -- See earlier commment about calling
+ -- Update_Result_For_Full_Coverage for such
+ -- components.
+
+ Update_Result_For_Full_Coverage
+ (Comp_Type => Etype (Comp_From_Type));
+
+ Comp_From_Type :=
+ Next_Component_Or_Discriminant (Comp_From_Type);
+ end loop;
+
+ pragma Assert
+ (Nat (Next_Part - Saved_Next_Part)
+ = Scalar_Part_Count (Etype (Expr)));
end;
elsif Is_Array_Type (Etype (Expr)) then
if Is_Non_Empty_List (Component_Associations (Expr)) then
@@ -1477,6 +1566,8 @@ package body Sem_Case is
end if;
end Traverse_Choice;
+ -- Start of processing for Parse_Choice
+
begin
if Nkind (Choice) = N_Others_Choice then
return (Is_Others => True);
@@ -1484,7 +1575,7 @@ package body Sem_Case is
Traverse_Choice (Choice);
-- Avoid returning uninitialized garbage in error case
- if not Done then
+ if Next_Part /= Part_Id'Last + 1 then
pragma Assert (Serious_Errors_Detected > 0);
Result.Ranges := (others => (Low => Uint_1, High => Uint_0));
end if;
@@ -2908,7 +2999,7 @@ package body Sem_Case is
begin
if Has_Predicates (Subtyp) then
Error_Msg_N
- ("subtype of case selector (or subcomponent thereof)" &
+ ("subtype of case selector (or subcomponent thereof) " &
"has predicate", N);
elsif Is_Discrete_Type (Subtyp) then
if not Is_Static_Subtype (Subtyp) then
@@ -2936,20 +3027,34 @@ package body Sem_Case is
end if;
Check_Component_Subtype (Component_Type (Subtyp));
elsif Is_Record_Type (Subtyp) then
- if Has_Discriminants (Subtyp) then
- Error_Msg_N
- ("type of case selector (or subcomponent thereof)" &
- "is discriminated", N);
- else
- declare
- Comp : Entity_Id := First_Component (Subtyp);
- begin
- while Present (Comp) loop
- Check_Component_Subtype (Etype (Comp));
- Next_Component (Comp);
- end loop;
- end;
+
+ if Has_Discriminants (Subtyp)
+ and then Is_Constrained (Subtyp)
+ and then not Has_Static_Discriminant_Constraint (Subtyp)
+ then
+ -- We are only disallowing nonstatic constraints for
+ -- subcomponent subtypes, not for the subtype of the
+ -- expression we are casing on. This test could be
+ -- implemented via an Is_Recursive_Call parameter if
+ -- that seems preferable.
+
+ if Subtyp /= Check_Choices.Subtyp then
+ Error_Msg_N
+ ("constrained discriminated subtype of case " &
+ "selector subcomponent has nonstatic " &
+ "constraint", N);
+ end if;
end if;
+
+ declare
+ Comp : Entity_Id :=
+ First_Component_Or_Discriminant (Base_Type (Subtyp));
+ begin
+ while Present (Comp) loop
+ Check_Component_Subtype (Etype (Comp));
+ Next_Component_Or_Discriminant (Comp);
+ end loop;
+ end;
else
Error_Msg_N
("type of case selector (or subcomponent thereof) is " &
@@ -3058,7 +3163,7 @@ package body Sem_Case is
-- bounds of its base type to determine the values covered by the
-- discrete choices.
- -- In Ada 2012, if the subtype has a non-static predicate the full
+ -- In Ada 2012, if the subtype has a nonstatic predicate the full
-- range of the base type must be covered as well.
if Is_OK_Static_Subtype (Subtyp) then
@@ -3075,7 +3180,7 @@ package body Sem_Case is
end if;
-- Obtain static bounds of type, unless this is a generic formal
- -- discrete type for which all choices will be non-static.
+ -- discrete type for which all choices will be nonstatic.
if not Is_Generic_Type (Root_Type (Bounds_Type))
or else Ekind (Bounds_Type) /= E_Enumeration_Type
@@ -3137,7 +3242,7 @@ package body Sem_Case is
if Has_Predicates (E) then
- -- Use of non-static predicate is an error
+ -- Use of nonstatic predicate is an error
if not Is_Discrete_Type (E)
or else not Has_Static_Predicate (E)
@@ -3298,6 +3403,30 @@ package body Sem_Case is
end Generic_Check_Choices;
+ -----------------------------------------
+ -- Has_Static_Discriminant_Constraint --
+ -----------------------------------------
+
+ function Has_Static_Discriminant_Constraint
+ (Subtyp : Entity_Id) return Boolean
+ is
+ begin
+ if Has_Discriminants (Subtyp) and then Is_Constrained (Subtyp) then
+ declare
+ DC_Elmt : Elmt_Id := First_Elmt (Discriminant_Constraint (Subtyp));
+ begin
+ while Present (DC_Elmt) loop
+ if not All_Composite_Constraints_Static (Node (DC_Elmt)) then
+ return False;
+ end if;
+ Next_Elmt (DC_Elmt);
+ end loop;
+ return True;
+ end;
+ end if;
+ return False;
+ end Has_Static_Discriminant_Constraint;
+
----------------------------
-- Is_Case_Choice_Pattern --
----------------------------
diff --git a/gcc/ada/sem_cat.ads b/gcc/ada/sem_cat.ads
index 3fa3339..90a713b 100644
--- a/gcc/ada/sem_cat.ads
+++ b/gcc/ada/sem_cat.ads
@@ -27,7 +27,7 @@
-- the semantic restrictions required for the categorization pragmas:
--
-- Preelaborate
--- Pure,
+-- Pure
-- Remote_Call_Interface
-- Remote_Types
-- Shared_Passive
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 339bb42..85c854f 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -5796,6 +5796,14 @@ package body Sem_Ch12 is
Set_SPARK_Mode (Gen_Unit);
end if;
+ -- Need to mark Anon_Id intrinsic before calling
+ -- Analyze_Instance_And_Renamings because this flag may be propagated
+ -- to other nodes.
+
+ if Is_Intrinsic_Subprogram (Gen_Unit) then
+ Set_Is_Intrinsic_Subprogram (Anon_Id);
+ end if;
+
Analyze_Instance_And_Renamings;
-- Restore SPARK_Mode from the context after analysis of the package
@@ -5817,7 +5825,6 @@ package body Sem_Ch12 is
-- not within the main unit.
if Is_Intrinsic_Subprogram (Gen_Unit) then
- Set_Is_Intrinsic_Subprogram (Anon_Id);
Set_Is_Intrinsic_Subprogram (Act_Decl_Id);
if Chars (Gen_Unit) = Name_Unchecked_Conversion then
@@ -9717,7 +9724,6 @@ package body Sem_Ch12 is
if Nkind (Par_N) = N_Package_Specification
and then Decls = Visible_Declarations (Par_N)
- and then Present (Private_Declarations (Par_N))
and then not Is_Empty_List (Private_Declarations (Par_N))
then
Decls := Private_Declarations (Par_N);
@@ -12825,7 +12831,7 @@ package body Sem_Ch12 is
Check_Volatility_Compatibility
(Act_T, A_Gen_T,
"actual type", "its corresponding formal type",
- Srcpos_Bearer => Act_T);
+ Srcpos_Bearer => Actual);
end if;
end Check_Shared_Variable_Control_Aspects;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index dcd5954..f0962ca0 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -4199,7 +4199,7 @@ package body Sem_Ch13 is
-- Case 2e: Annotate aspect
- when Aspect_Annotate =>
+ when Aspect_Annotate | Aspect_GNAT_Annotate =>
declare
Args : List_Id;
Pargs : List_Id;
@@ -5230,44 +5230,64 @@ package body Sem_Ch13 is
F := First_Formal (Subp);
- if No (F)
- or else Etype (F) /= Class_Wide_Type (RTE (RE_Root_Buffer_Type))
+ if No (F) then
+ return False;
+ end if;
+
+ if Base_Type (Etype (F))
+ /= Class_Wide_Type (RTE (RE_Root_Buffer_Type))
then
+ if Report then
+ Error_Msg_N
+ ("wrong type for Put_Image procedure''s first parameter",
+ Parameter_Type (Parent (F)));
+ end if;
+
return False;
end if;
- Next_Formal (F);
+ if Parameter_Mode (F) /= E_In_Out_Parameter then
+ if Report then
+ Error_Msg_N
+ ("wrong mode for Put_Image procedure''s first parameter",
+ Parent (F));
+ end if;
- if Parameter_Mode (F) /= E_In_Parameter then
return False;
end if;
+ Next_Formal (F);
+
Typ := Etype (F);
-- Verify that the prefix of the attribute and the local name for
-- the type of the formal match.
- if Typ /= Ent then
- return False;
- end if;
+ if Base_Type (Typ) /= Base_Type (Ent) then
+ if Report then
+ Error_Msg_N
+ ("wrong type for Put_Image procedure''s second parameter",
+ Parameter_Type (Parent (F)));
+ end if;
- if Present (Next_Formal (F)) then
return False;
+ end if;
- elsif not Is_Scalar_Type (Typ)
- and then not Is_First_Subtype (Typ)
- then
- if Report and not Is_First_Subtype (Typ) then
+ if Parameter_Mode (F) /= E_In_Parameter then
+ if Report then
Error_Msg_N
- ("subtype of formal in Put_Image operation must be a "
- & "first subtype", Parameter_Type (Parent (F)));
+ ("wrong mode for Put_Image procedure''s second parameter",
+ Parent (F));
end if;
return False;
+ end if;
- else
- return True;
+ if Present (Next_Formal (F)) then
+ return False;
end if;
+
+ return True;
end Has_Good_Profile;
-- Start of processing for Analyze_Put_Image_TSS_Definition
@@ -5386,7 +5406,7 @@ package body Sem_Ch13 is
if No (F)
or else Ekind (Etype (F)) /= E_Anonymous_Access_Type
- or else Designated_Type (Etype (F)) /=
+ or else Base_Type (Designated_Type (Etype (F))) /=
Class_Wide_Type (RTE (RE_Root_Stream_Type))
then
return False;
@@ -7160,109 +7180,136 @@ package body Sem_Ch13 is
Set_SSO_Set_High_By_Default (Base_Type (U_Ent), False);
end if;
- ----------
- -- Size --
- ----------
+ ------------------------
+ -- Size or Value_Size --
+ ------------------------
- -- Size attribute definition clause
+ -- Size or Value_Size attribute definition clause. These are treated
+ -- the same, except that Size is allowed on objects, and Value_Size
+ -- is allowed on nonfirst subtypes. First subtypes allow both Size
+ -- and Value_Size; the treatment is the same for both.
- when Attribute_Size => Size : declare
+ when Attribute_Size | Attribute_Value_Size => Size : declare
Size : constant Uint := Static_Integer (Expr);
- Etyp : Entity_Id;
- Biased : Boolean;
+
+ Attr_Name : constant String :=
+ (if Id = Attribute_Size then "size"
+ elsif Id = Attribute_Value_Size then "value size"
+ else ""); -- can't happen
+ -- Name of the attribute for printing in messages
+
+ OK_Prefix : constant Boolean :=
+ (if Id = Attribute_Size then
+ Ekind (U_Ent) in Type_Kind | Constant_Or_Variable_Kind
+ elsif Id = Attribute_Value_Size then
+ Ekind (U_Ent) in Type_Kind
+ else False); -- can't happen
+ -- For X'Size, X can be a type or object; for X'Value_Size,
+ -- X can be a type. Note that we already checked that 'Size
+ -- can be specified only for a first subytype.
begin
FOnly := True;
- if Duplicate_Clause then
- null;
+ if not OK_Prefix then
+ Error_Msg_N (Attr_Name & " cannot be given for &", Nam);
- elsif not Is_Type (U_Ent)
- and then Ekind (U_Ent) /= E_Variable
- and then Ekind (U_Ent) /= E_Constant
- then
- Error_Msg_N ("size cannot be given for &", Nam);
+ elsif Duplicate_Clause then
+ null;
elsif Is_Array_Type (U_Ent)
and then not Is_Constrained (U_Ent)
then
Error_Msg_N
- ("size cannot be given for unconstrained array", Nam);
+ (Attr_Name & " cannot be given for unconstrained array", Nam);
elsif Size /= No_Uint then
- if Is_Type (U_Ent) then
- Etyp := U_Ent;
- else
- Etyp := Etype (U_Ent);
- end if;
+ declare
+ Etyp : constant Entity_Id :=
+ (if Is_Type (U_Ent) then U_Ent else Etype (U_Ent));
+
+ begin
+ -- Check size, note that Gigi is in charge of checking that
+ -- the size of an array or record type is OK. Also we do not
+ -- check the size in the ordinary fixed-point case, since
+ -- it is too early to do so (there may be subsequent small
+ -- clause that affects the size). We can check the size if
+ -- a small clause has already been given.
+
+ if not Is_Ordinary_Fixed_Point_Type (U_Ent)
+ or else Has_Small_Clause (U_Ent)
+ then
+ declare
+ Biased : Boolean;
+ begin
+ Check_Size (Expr, Etyp, Size, Biased);
+ Set_Biased (U_Ent, N, Attr_Name & " clause", Biased);
+ end;
+ end if;
- -- Check size, note that Gigi is in charge of checking that the
- -- size of an array or record type is OK. Also we do not check
- -- the size in the ordinary fixed-point case, since it is too
- -- early to do so (there may be subsequent small clause that
- -- affects the size). We can check the size if a small clause
- -- has already been given.
+ -- For types, set RM_Size and Esize if appropriate
- if not Is_Ordinary_Fixed_Point_Type (U_Ent)
- or else Has_Small_Clause (U_Ent)
- then
- Check_Size (Expr, Etyp, Size, Biased);
- Set_Biased (U_Ent, N, "size clause", Biased);
- end if;
+ if Is_Type (U_Ent) then
+ Set_RM_Size (U_Ent, Size);
- -- For types set RM_Size and Esize if possible
+ -- If we are specifying the Size or Value_Size of a
+ -- first subtype, then for elementary types, increase
+ -- Object_Size to power of 2, but not less than a storage
+ -- unit in any case (normally this means it will be byte
+ -- addressable).
- if Is_Type (U_Ent) then
- Set_RM_Size (U_Ent, Size);
+ -- For all other types, nothing else to do, we leave
+ -- Esize (object size) unset; the back end will set it
+ -- from the size and alignment in an appropriate manner.
- -- For elementary types, increase Object_Size to power of 2,
- -- but not less than a storage unit in any case (normally
- -- this means it will be byte addressable).
+ -- In both cases, we check whether the alignment must be
+ -- reset in the wake of the size change.
- -- For all other types, nothing else to do, we leave Esize
- -- (object size) unset, the back end will set it from the
- -- size and alignment in an appropriate manner.
+ -- For nonfirst subtypes ('Value_Size only), we do
+ -- nothing here.
- -- In both cases, we check whether the alignment must be
- -- reset in the wake of the size change.
+ if Is_First_Subtype (U_Ent) then
+ if Is_Elementary_Type (U_Ent) then
+ if Size <= System_Storage_Unit then
+ Init_Esize (U_Ent, System_Storage_Unit);
+ elsif Size <= 16 then
+ Init_Esize (U_Ent, 16);
+ elsif Size <= 32 then
+ Init_Esize (U_Ent, 32);
+ else
+ Set_Esize (U_Ent, (Size + 63) / 64 * 64);
+ end if;
- if Is_Elementary_Type (U_Ent) then
- if Size <= System_Storage_Unit then
- Init_Esize (U_Ent, System_Storage_Unit);
- elsif Size <= 16 then
- Init_Esize (U_Ent, 16);
- elsif Size <= 32 then
- Init_Esize (U_Ent, 32);
- else
- Set_Esize (U_Ent, (Size + 63) / 64 * 64);
+ Alignment_Check_For_Size_Change
+ (U_Ent, Esize (U_Ent));
+ else
+ Alignment_Check_For_Size_Change (U_Ent, Size);
+ end if;
end if;
- Alignment_Check_For_Size_Change (U_Ent, Esize (U_Ent));
- else
- Alignment_Check_For_Size_Change (U_Ent, Size);
- end if;
+ -- For Object'Size, set Esize only
- -- For objects, set Esize only
+ else
+ if Is_Elementary_Type (Etyp)
+ and then Size /= System_Storage_Unit
+ and then Size /= 16
+ and then Size /= 32
+ and then Size /= 64
+ and then Size /= System_Max_Integer_Size
+ then
+ Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
+ Error_Msg_Uint_2 :=
+ UI_From_Int (System_Max_Integer_Size);
+ Error_Msg_N
+ ("size for primitive object must be a power of 2 in "
+ & "the range ^-^", N);
+ end if;
- else
- if Is_Elementary_Type (Etyp)
- and then Size /= System_Storage_Unit
- and then Size /= 16
- and then Size /= 32
- and then Size /= 64
- and then Size /= System_Max_Integer_Size
- then
- Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
- Error_Msg_Uint_2 := UI_From_Int (System_Max_Integer_Size);
- Error_Msg_N
- ("size for primitive object must be a power of 2 in "
- & "the range ^-^", N);
+ Set_Esize (U_Ent, Size);
end if;
- Set_Esize (U_Ent, Size);
- end if;
-
- Set_Has_Size_Clause (U_Ent);
+ Set_Has_Size_Clause (U_Ent);
+ end;
end if;
end Size;
@@ -7724,39 +7771,6 @@ package body Sem_Ch13 is
end if;
end Stream_Size;
- ----------------
- -- Value_Size --
- ----------------
-
- -- Value_Size attribute definition clause
-
- when Attribute_Value_Size => Value_Size : declare
- Size : constant Uint := Static_Integer (Expr);
- Biased : Boolean;
-
- begin
- if not Is_Type (U_Ent) then
- Error_Msg_N ("Value_Size cannot be given for &", Nam);
-
- elsif Duplicate_Clause then
- null;
-
- elsif Is_Array_Type (U_Ent)
- and then not Is_Constrained (U_Ent)
- then
- Error_Msg_N
- ("Value_Size cannot be given for unconstrained array", Nam);
-
- else
- if Is_Elementary_Type (U_Ent) then
- Check_Size (Expr, U_Ent, Size, Biased);
- Set_Biased (U_Ent, N, "value size clause", Biased);
- end if;
-
- Set_RM_Size (U_Ent, Size);
- end if;
- end Value_Size;
-
-----------------------
-- Variable_Indexing --
-----------------------
@@ -10100,11 +10114,11 @@ package body Sem_Ch13 is
then
return;
- -- Do not generate predicate bodies within a generic unit. The
- -- expressions have been analyzed already, and the bodies play
- -- no role if not within an executable unit. However, if a static
- -- predicate is present it must be processed for legality checks
- -- such as case coverage in an expression.
+ -- Do not generate predicate bodies within a generic unit. The
+ -- expressions have been analyzed already, and the bodies play no role
+ -- if not within an executable unit. However, if a static predicate is
+ -- present it must be processed for legality checks such as case
+ -- coverage in an expression.
elsif Inside_A_Generic
and then not Has_Static_Predicate_Aspect (Typ)
@@ -10768,7 +10782,9 @@ 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 in Aspect_Dynamic_Predicate | Aspect_Predicate then
+ if A_Id in Aspect_Dynamic_Predicate | Aspect_Predicate |
+ Aspect_Static_Predicate
+ then
Push_Type (Ent);
Preanalyze_Spec_Expression (Freeze_Expr, Standard_Boolean);
Pop_Type (Ent);
@@ -10799,6 +10815,7 @@ package body Sem_Ch13 is
if A_Id in Aspect_Dynamic_Predicate
| Aspect_Predicate
| Aspect_Priority
+ | Aspect_Static_Predicate
then
Push_Type (Ent);
Check_Aspect_At_Freeze_Point (ASN);
@@ -10826,6 +10843,7 @@ package body Sem_Ch13 is
| Aspect_Dynamic_Predicate
| Aspect_Predicate
| Aspect_Priority
+ | Aspect_Static_Predicate
then
Push_Type (Ent);
Preanalyze_Spec_Expression (End_Decl_Expr, T);
@@ -11097,6 +11115,7 @@ package body Sem_Ch13 is
| Aspect_Extensions_Visible
| Aspect_Ghost
| Aspect_Global
+ | Aspect_GNAT_Annotate
| Aspect_Implicit_Dereference
| Aspect_Initial_Condition
| Aspect_Initializes
@@ -12355,7 +12374,7 @@ package body Sem_Ch13 is
-- length (it may for example be appropriate to round up the size
-- to some convenient boundary, based on alignment considerations, etc).
- if Unknown_RM_Size (Rectype)
+ if not Known_RM_Size (Rectype)
and then Hbit + 1 <= 32
and then not Strict_Alignment (Rectype)
then
@@ -15027,9 +15046,15 @@ package body Sem_Ch13 is
or else N /= Selector_Name (Parent (N)))
then
Find_Direct_Name (N);
- Set_Entity (N, Empty);
- -- The name is component association needs no resolution
+ -- Reset the Entity if N is overloaded since the entity may not
+ -- be the correct one.
+
+ if Is_Overloaded (N) then
+ Set_Entity (N, Empty);
+ end if;
+
+ -- The name in a component association needs no resolution
elsif Nkind (N) = N_Component_Association then
Dummy := Resolve_Name (Expression (N));
@@ -15072,24 +15097,23 @@ package body Sem_Ch13 is
-- types. These will require special handling???.
when Aspect_Invariant
- | Aspect_Predicate
| Aspect_Predicate_Failure
=>
null;
when Aspect_Dynamic_Predicate
| Aspect_Static_Predicate
+ | Aspect_Predicate
=>
- -- Build predicate function specification and preanalyze
- -- expression after type replacement. The function
- -- declaration must be analyzed in the scope of the type,
- -- but the expression can reference components and
- -- discriminants of the type.
+ -- Preanalyze expression after type replacement to catch
+ -- name resolution errors if the predicate function has
+ -- not been built yet.
+ -- Note that we cannot use Preanalyze_Spec_Expression
+ -- because of the special handling required for
+ -- quantifiers, see comments on Resolve_Aspect_Expression
+ -- above.
if No (Predicate_Function (E)) then
- Discard_Node
- (Build_Predicate_Function_Declaration (E));
-
Push_Type (E);
Resolve_Aspect_Expression (Expr);
Pop_Type (E);
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 7579812..3b21484 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -115,17 +115,17 @@ package Sem_Ch13 is
Siz : Uint;
Biased : out Boolean);
-- Called when size Siz is specified for subtype T. This subprogram checks
- -- that the size is appropriate, posting errors on node N as required.
- -- This check is effective for elementary types and bit-packed arrays.
- -- For other non-elementary types, a check is only made if an explicit
- -- size has been given for the type (and the specified size must match).
- -- The parameter Biased is set False if the size specified did not require
- -- the use of biased representation, and True if biased representation
- -- was required to meet the size requirement. Note that Biased is only
- -- set if the type is not currently biased, but biasing it is the only
- -- way to meet the requirement. If the type is currently biased, then
- -- this biased size is used in the initial check, and Biased is False.
- -- For a Component_Size clause, T is the component type.
+ -- that the size is appropriate, posting errors on node N as required. This
+ -- check is effective for elementary types and bit-packed arrays. For
+ -- composite types, a check is only made if an explicit size has been given
+ -- for the type (and the specified size must match). The parameter Biased
+ -- is set False if the size specified did not require the use of biased
+ -- representation, and True if biased representation was required to meet
+ -- the size requirement. Note that Biased is only set if the type is not
+ -- currently biased, but biasing it is the only way to meet the
+ -- requirement. If the type is currently biased, then this biased size is
+ -- used in the initial check, and Biased is False. For a Component_Size
+ -- clause, T is the component type.
function Has_Compatible_Representation
(Target_Type, Operand_Type : Entity_Id) return Boolean;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 7dfb5c8..e9b4456 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -3261,6 +3261,40 @@ package body Sem_Ch3 is
return;
end if;
+ -- Set the primitives list of the full type and its base type when
+ -- needed. T may be E_Void in cases of earlier errors, and in that
+ -- case we bypass this.
+
+ if Ekind (T) /= E_Void
+ and then not Present (Direct_Primitive_Operations (T))
+ then
+ if Etype (T) = T then
+ Set_Direct_Primitive_Operations (T, New_Elmt_List);
+
+ -- If Etype of T is the base type (as opposed to a parent type) and
+ -- already has an associated list of primitive operations, then set
+ -- T's primitive list to the base type's list. Otherwise, create a
+ -- new empty primitives list and share the list between T and its
+ -- base type. The lists need to be shared in common between the two.
+
+ elsif Etype (T) = Base_Type (T) then
+
+ if not Present (Direct_Primitive_Operations (Base_Type (T))) then
+ Set_Direct_Primitive_Operations
+ (Base_Type (T), New_Elmt_List);
+ end if;
+
+ Set_Direct_Primitive_Operations
+ (T, Direct_Primitive_Operations (Base_Type (T)));
+
+ -- Case where the Etype is a parent type, so we need a new primitives
+ -- list for T.
+
+ else
+ Set_Direct_Primitive_Operations (T, New_Elmt_List);
+ end if;
+ end if;
+
-- Some common processing for all types
Set_Depends_On_Private (T, Has_Private_Component (T));
@@ -3493,9 +3527,7 @@ package body Sem_Ch3 is
-- Check runtime support for synchronized interfaces
- if (Is_Task_Interface (T)
- or else Is_Protected_Interface (T)
- or else Is_Synchronized_Interface (T))
+ if Is_Concurrent_Interface (T)
and then not RTE_Available (RE_Select_Specific_Data)
then
Error_Msg_CRT ("synchronized interfaces", T);
@@ -5708,6 +5740,14 @@ package body Sem_Ch3 is
Inherit_Predicate_Flags (Id, T);
end if;
+ -- When prefixed calls are enabled for untagged types, the subtype
+ -- shares the primitive operations of its base type.
+
+ if Extensions_Allowed then
+ Set_Direct_Primitive_Operations
+ (Id, Direct_Primitive_Operations (Base_Type (T)));
+ end if;
+
if Etype (Id) = Any_Type then
goto Leave;
end if;
@@ -5739,7 +5779,16 @@ package body Sem_Ch3 is
((In_Instance and then not Comes_From_Source (N))
or else No (Aspect_Specifications (N)))
then
- Set_Subprograms_For_Type (Id, Subprograms_For_Type (T));
+ -- Inherit Subprograms_For_Type from the full view, if present
+
+ if Present (Full_View (T))
+ and then Subprograms_For_Type (Full_View (T)) /= No_Elist
+ then
+ Set_Subprograms_For_Type
+ (Id, Subprograms_For_Type (Full_View (T)));
+ else
+ Set_Subprograms_For_Type (Id, Subprograms_For_Type (T));
+ end if;
-- If the current declaration created both a private and a full view,
-- then propagate Predicate_Function to the latter as well.
@@ -9270,9 +9319,7 @@ package body Sem_Ch3 is
and then Is_Limited_Record (Full_View (Parent_Type)))
then
if not Is_Interface (Parent_Type)
- or else Is_Synchronized_Interface (Parent_Type)
- or else Is_Protected_Interface (Parent_Type)
- or else Is_Task_Interface (Parent_Type)
+ or else Is_Concurrent_Interface (Parent_Type)
then
Set_Is_Limited_Record (Derived_Type);
end if;
@@ -9511,6 +9558,13 @@ package body Sem_Ch3 is
end;
end if;
+ -- When prefixed-call syntax is allowed for untagged types, initialize
+ -- the list of primitive operations to an empty list.
+
+ if Extensions_Allowed and then not Is_Tagged then
+ Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);
+ end if;
+
-- Set fields for tagged types
if Is_Tagged then
@@ -9989,6 +10043,28 @@ package body Sem_Ch3 is
return;
end if;
+ -- If not already set, initialize the derived type's list of primitive
+ -- operations to an empty element list.
+
+ if not Present (Direct_Primitive_Operations (Derived_Type)) then
+ Set_Direct_Primitive_Operations (Derived_Type, New_Elmt_List);
+
+ -- If Etype of the derived type is the base type (as opposed to
+ -- a parent type) and doesn't have an associated list of primitive
+ -- operations, then set the base type's primitive list to the
+ -- derived type's list. The lists need to be shared in common
+ -- between the two.
+
+ if Etype (Derived_Type) = Base_Type (Derived_Type)
+ and then
+ not Present (Direct_Primitive_Operations (Etype (Derived_Type)))
+ then
+ Set_Direct_Primitive_Operations
+ (Etype (Derived_Type),
+ Direct_Primitive_Operations (Derived_Type));
+ end if;
+ end if;
+
-- Set delayed freeze and then derive subprograms, we need to do this
-- in this order so that derived subprograms inherit the derived freeze
-- if necessary.
@@ -11149,12 +11225,29 @@ package body Sem_Ch3 is
if Present (Overridden_Operation (Subp))
and then No_Return (Overridden_Operation (Subp))
- and then not No_Return (Subp)
then
- Error_Msg_N ("overriding subprogram & must be No_Return", Subp);
- Error_Msg_N
- ("\since overridden subprogram is No_Return (RM 6.5.1(6/2))",
- Subp);
+
+ -- If the subprogram is a renaming, check that the renamed
+ -- subprogram is No_Return.
+
+ if Present (Renamed_Or_Alias (Subp)) then
+ if not No_Return (Renamed_Or_Alias (Subp)) then
+ Error_Msg_NE ("subprogram & must be No_Return",
+ Subp,
+ Renamed_Or_Alias (Subp));
+ Error_Msg_N ("\since renaming & overrides No_Return "
+ & "subprogram (RM 6.5.1(6/2))",
+ Subp);
+ end if;
+
+ -- Make sure that the subprogram itself is No_Return.
+
+ elsif not No_Return (Subp) then
+ Error_Msg_N ("overriding subprogram & must be No_Return", Subp);
+ Error_Msg_N
+ ("\since overridden subprogram is No_Return (RM 6.5.1(6/2))",
+ Subp);
+ end if;
end if;
-- If the operation is a wrapper for a synchronized primitive, it
@@ -16740,7 +16833,7 @@ package body Sem_Ch3 is
Set_Etype (Derived_Type, Implicit_Base);
Set_Size_Info (Derived_Type, Parent_Type);
- if Unknown_RM_Size (Derived_Type) then
+ if not Known_RM_Size (Derived_Type) then
Set_RM_Size (Derived_Type, RM_Size (Parent_Type));
end if;
@@ -18997,56 +19090,6 @@ package body Sem_Ch3 is
return False;
end Is_EVF_Procedure;
- -----------------------
- -- Is_Null_Extension --
- -----------------------
-
- function Is_Null_Extension (T : Entity_Id) return Boolean is
- Type_Decl : constant Node_Id := Parent (Base_Type (T));
- Comp_List : Node_Id;
- Comp : Node_Id;
-
- begin
- if Nkind (Type_Decl) /= N_Full_Type_Declaration
- or else not Is_Tagged_Type (T)
- or else Nkind (Type_Definition (Type_Decl)) /=
- N_Derived_Type_Definition
- or else No (Record_Extension_Part (Type_Definition (Type_Decl)))
- then
- return False;
- end if;
-
- Comp_List :=
- Component_List (Record_Extension_Part (Type_Definition (Type_Decl)));
-
- if Present (Discriminant_Specifications (Type_Decl)) then
- return False;
-
- elsif Present (Comp_List)
- and then Is_Non_Empty_List (Component_Items (Comp_List))
- then
- Comp := First (Component_Items (Comp_List));
-
- -- Only user-defined components are relevant. The component list
- -- may also contain a parent component and internal components
- -- corresponding to secondary tags, but these do not determine
- -- whether this is a null extension.
-
- while Present (Comp) loop
- if Comes_From_Source (Comp) then
- return False;
- end if;
-
- Next (Comp);
- end loop;
-
- return True;
-
- else
- return True;
- end if;
- end Is_Null_Extension;
-
--------------------------
-- Is_Private_Primitive --
--------------------------
@@ -21048,48 +21091,48 @@ package body Sem_Ch3 is
end loop;
end;
- -- If the private view was tagged, copy the new primitive operations
- -- from the private view to the full view.
+ declare
+ Disp_Typ : Entity_Id;
+ Full_List : Elist_Id;
+ Prim : Entity_Id;
+ Prim_Elmt : Elmt_Id;
+ Priv_List : Elist_Id;
+
+ function Contains
+ (E : Entity_Id;
+ L : Elist_Id) return Boolean;
+ -- Determine whether list L contains element E
+
+ --------------
+ -- Contains --
+ --------------
+
+ function Contains
+ (E : Entity_Id;
+ L : Elist_Id) return Boolean
+ is
+ List_Elmt : Elmt_Id;
- if Is_Tagged_Type (Full_T) then
- declare
- Disp_Typ : Entity_Id;
- Full_List : Elist_Id;
- Prim : Entity_Id;
- Prim_Elmt : Elmt_Id;
- Priv_List : Elist_Id;
-
- function Contains
- (E : Entity_Id;
- L : Elist_Id) return Boolean;
- -- Determine whether list L contains element E
-
- --------------
- -- Contains --
- --------------
-
- function Contains
- (E : Entity_Id;
- L : Elist_Id) return Boolean
- is
- List_Elmt : Elmt_Id;
+ begin
+ List_Elmt := First_Elmt (L);
+ while Present (List_Elmt) loop
+ if Node (List_Elmt) = E then
+ return True;
+ end if;
- begin
- List_Elmt := First_Elmt (L);
- while Present (List_Elmt) loop
- if Node (List_Elmt) = E then
- return True;
- end if;
+ Next_Elmt (List_Elmt);
+ end loop;
- Next_Elmt (List_Elmt);
- end loop;
+ return False;
+ end Contains;
- return False;
- end Contains;
+ -- Start of processing
- -- Start of processing
+ begin
+ -- If the private view was tagged, copy the new primitive operations
+ -- from the private view to the full view.
- begin
+ if Is_Tagged_Type (Full_T) then
if Is_Tagged_Type (Priv_T) then
Priv_List := Primitive_Operations (Priv_T);
Prim_Elmt := First_Elmt (Priv_List);
@@ -21223,8 +21266,23 @@ package body Sem_Ch3 is
Propagate_Concurrent_Flags (Class_Wide_Type (Priv_T), Full_T);
end if;
- end;
- end if;
+
+ -- For untagged types, copy the primitives across from the private
+ -- view to the full view (when extensions are allowed), for support
+ -- of prefixed calls (when extensions are enabled).
+
+ elsif Extensions_Allowed then
+ Priv_List := Primitive_Operations (Priv_T);
+ Prim_Elmt := First_Elmt (Priv_List);
+
+ Full_List := Primitive_Operations (Full_T);
+ while Present (Prim_Elmt) loop
+ Prim := Node (Prim_Elmt);
+ Append_Elmt (Prim, Full_List);
+ Next_Elmt (Prim_Elmt);
+ end loop;
+ end if;
+ end;
-- Ada 2005 AI 161: Check preelaborable initialization consistency
diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads
index dcd4a34..eedb98c 100644
--- a/gcc/ada/sem_ch3.ads
+++ b/gcc/ada/sem_ch3.ads
@@ -176,11 +176,6 @@ package Sem_Ch3 is
-- corresponding to that discriminant in the constraint that specifies its
-- value.
- function Is_Null_Extension (T : Entity_Id) return Boolean;
- -- Returns True if the tagged type T has an N_Full_Type_Declaration that
- -- is a null extension, meaning that it has an extension part without any
- -- components and does not have a known discriminant part.
-
function Is_Visible_Component
(C : Entity_Id;
N : Node_Id := Empty) return Boolean;
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index ede257b..c052022 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -889,16 +889,6 @@ package body Sem_Ch4 is
Check_Restriction (No_Local_Allocators, N);
end if;
- if SPARK_Mode = On
- and then Comes_From_Source (N)
- and then not Is_OK_Volatile_Context (Context => Parent (N),
- Obj_Ref => N,
- Check_Actuals => False)
- then
- Error_Msg_N
- ("allocator cannot appear in this context (SPARK RM 7.1.3(10))", N);
- end if;
-
if Serious_Errors_Detected > Sav_Errs then
Set_Error_Posted (N);
Set_Etype (N, Any_Type);
@@ -5012,8 +5002,11 @@ package body Sem_Ch4 is
-- Ada 2005 (AI05-0030): In the case of dispatching requeue, the
-- selected component should resolve to a name.
+ -- Extension feature: Also support calls with prefixed views for
+ -- untagged record types.
+
if Ada_Version >= Ada_2005
- and then Is_Tagged_Type (Prefix_Type)
+ and then (Is_Tagged_Type (Prefix_Type) or else Extensions_Allowed)
and then not Is_Concurrent_Type (Prefix_Type)
then
if Nkind (Parent (N)) = N_Generic_Association
@@ -5086,6 +5079,15 @@ package body Sem_Ch4 is
Next_Entity (Comp);
end loop;
+ -- Extension feature: Also support calls with prefixed views for
+ -- untagged private types.
+
+ if Extensions_Allowed then
+ if Try_Object_Operation (N) then
+ return;
+ end if;
+ end if;
+
elsif Is_Concurrent_Type (Prefix_Type) then
-- Find visible operation with given name. For a protected type,
@@ -5338,6 +5340,14 @@ package body Sem_Ch4 is
Set_Is_Overloaded (N, Is_Overloaded (Sel));
+ -- Extension feature: Also support calls with prefixed views for
+ -- untagged types.
+
+ elsif Extensions_Allowed
+ and then Try_Object_Operation (N)
+ then
+ return;
+
else
-- Invalid prefix
@@ -5461,7 +5471,9 @@ package body Sem_Ch4 is
Apply_Compile_Time_Constraint_Error
(N, "component not present in }??",
CE_Discriminant_Check_Failed,
- Ent => Prefix_Type);
+ Ent => Prefix_Type,
+ Emit_Message =>
+ SPARK_Mode = On or not In_Instance_Not_Visible);
return;
end if;
@@ -9546,7 +9558,15 @@ package body Sem_Ch4 is
-- type, this is not a prefixed call. Restore the previous type as
-- the current one is not a legal candidate.
- if not Is_Tagged_Type (Obj_Type)
+ -- Extension feature: Calls with prefixed views are also supported
+ -- for untagged types, so skip the early return when extensions are
+ -- enabled, unless the type doesn't have a primitive operations list
+ -- (such as in the case of predefined types).
+
+ if (not Is_Tagged_Type (Obj_Type)
+ and then
+ (not Extensions_Allowed
+ or else not Present (Primitive_Operations (Obj_Type))))
or else Is_Incomplete_Type (Obj_Type)
then
Obj_Type := Prev_Obj_Type;
@@ -9564,6 +9584,36 @@ package body Sem_Ch4 is
Try_Primitive_Operation
(Call_Node => New_Call_Node,
Node_To_Replace => Node_To_Replace);
+
+ -- Extension feature: In the case where the prefix is of an
+ -- access type, and a primitive wasn't found for the designated
+ -- type, then if the access type has primitives we attempt a
+ -- prefixed call using one of its primitives. (It seems that
+ -- this isn't quite right to give preference to the designated
+ -- type in the case where both the access and designated types
+ -- have homographic prefixed-view operations that could result
+ -- in an ambiguity, but handling properly may be tricky. ???)
+
+ if Extensions_Allowed
+ and then not Prim_Result
+ and then Is_Named_Access_Type (Prev_Obj_Type)
+ and then Present (Direct_Primitive_Operations (Prev_Obj_Type))
+ then
+ -- Temporarily reset Obj_Type to the original access type
+
+ Obj_Type := Prev_Obj_Type;
+
+ Prim_Result :=
+ Try_Primitive_Operation
+ (Call_Node => New_Call_Node,
+ Node_To_Replace => Node_To_Replace);
+
+ -- Restore Obj_Type to the designated type (is this really
+ -- necessary, or should it only be done when Prim_Result is
+ -- still False?).
+
+ Obj_Type := Designated_Type (Obj_Type);
+ end if;
end if;
-- Check if there is a class-wide subprogram covering the
@@ -9903,7 +9953,7 @@ package body Sem_Ch4 is
-- be the corresponding record of a synchronized type.
return Obj_Type = Typ
- or else Base_Type (Obj_Type) = Typ
+ or else Base_Type (Obj_Type) = Base_Type (Typ)
or else Corr_Type = Typ
-- Object may be of a derived type whose parent has unknown
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 3c98d73..7a8d0cc 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -33,6 +33,7 @@ with Einfo.Utils; use Einfo.Utils;
with Errout; use Errout;
with Expander; use Expander;
with Exp_Ch6; use Exp_Ch6;
+with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze; use Freeze;
with Ghost; use Ghost;
@@ -479,12 +480,11 @@ package body Sem_Ch5 is
Mark_And_Set_Ghost_Assignment (N);
if Has_Target_Names (N) then
+ pragma Assert (No (Current_Assignment));
Current_Assignment := N;
Expander_Mode_Save_And_Set (False);
Save_Full_Analysis := Full_Analysis;
Full_Analysis := False;
- else
- Current_Assignment := Empty;
end if;
Analyze (Lhs);
@@ -979,7 +979,92 @@ package body Sem_Ch5 is
end if;
if Is_Scalar_Type (T1) then
- Apply_Scalar_Range_Check (Rhs, Etype (Lhs));
+ declare
+
+ function Omit_Range_Check_For_Streaming return Boolean;
+ -- Return True if this assignment statement is the expansion of
+ -- a Some_Scalar_Type'Read procedure call such that all conditions
+ -- of 13.3.2(35)'s "no check is made" rule are met.
+
+ ------------------------------------
+ -- Omit_Range_Check_For_Streaming --
+ ------------------------------------
+
+ function Omit_Range_Check_For_Streaming return Boolean is
+ begin
+ -- Have we got an implicitly generated assignment to a
+ -- component of a composite object? If not, return False.
+
+ if Comes_From_Source (N)
+ or else Serious_Errors_Detected > 0
+ or else Nkind (Lhs)
+ not in N_Selected_Component | N_Indexed_Component
+ then
+ return False;
+ end if;
+
+ declare
+ Pref : constant Node_Id := Prefix (Lhs);
+ begin
+ -- Are we in the implicitly-defined Read subprogram
+ -- for a composite type, reading the value of a scalar
+ -- component from the stream? If not, return False.
+
+ if Nkind (Pref) /= N_Identifier
+ or else not Is_TSS (Scope (Entity (Pref)), TSS_Stream_Read)
+ then
+ return False;
+ end if;
+
+ -- Return False if Default_Value or Default_Component_Value
+ -- aspect applies.
+
+ if Has_Default_Aspect (Etype (Lhs))
+ or else Has_Default_Aspect (Etype (Pref))
+ then
+ return False;
+
+ -- Are we assigning to a record component (as opposed to
+ -- an array component)?
+
+ elsif Nkind (Lhs) = N_Selected_Component then
+
+ -- Are we assigning to a nondiscriminant component
+ -- that lacks a default initial value expression?
+ -- If so, return True.
+
+ declare
+ Comp_Id : constant Entity_Id :=
+ Original_Record_Component
+ (Entity (Selector_Name (Lhs)));
+ begin
+ if Ekind (Comp_Id) = E_Component
+ and then Nkind (Parent (Comp_Id))
+ = N_Component_Declaration
+ and then
+ not Present (Expression (Parent (Comp_Id)))
+ then
+ return True;
+ end if;
+ return False;
+ end;
+
+ -- We are assigning to a component of an array
+ -- (and we tested for both Default_Value and
+ -- Default_Component_Value above), so return True.
+
+ else
+ pragma Assert (Nkind (Lhs) = N_Indexed_Component);
+ return True;
+ end if;
+ end;
+ end Omit_Range_Check_For_Streaming;
+
+ begin
+ if not Omit_Range_Check_For_Streaming then
+ Apply_Scalar_Range_Check (Rhs, Etype (Lhs));
+ end if;
+ end;
-- For array types, verify that lengths match. If the right hand side
-- is a function call that has been inlined, the assignment has been
@@ -1216,6 +1301,7 @@ package body Sem_Ch5 is
if Has_Target_Names (N) then
Expander_Mode_Restore;
Full_Analysis := Save_Full_Analysis;
+ Current_Assignment := Empty;
end if;
pragma Assert (not Should_Transform_BIP_Assignment (Typ => T1));
@@ -2090,9 +2176,11 @@ package body Sem_Ch5 is
-- indicator, verify that the container type has an Iterate aspect that
-- implements the reversible iterator interface.
- procedure Check_Subtype_Indication (Comp_Type : Entity_Id);
+ procedure Check_Subtype_Definition (Comp_Type : Entity_Id);
-- If a subtype indication is present, verify that it is consistent
-- with the component type of the array or container name.
+ -- In Ada 2022, the subtype indication may be an access definition,
+ -- if the array or container has elements of an anonymous access type.
function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id;
-- For containers with Iterator and related aspects, the cursor is
@@ -2123,24 +2211,46 @@ package body Sem_Ch5 is
end Check_Reverse_Iteration;
-------------------------------
- -- Check_Subtype_Indication --
+ -- Check_Subtype_Definition --
-------------------------------
- procedure Check_Subtype_Indication (Comp_Type : Entity_Id) is
+ procedure Check_Subtype_Definition (Comp_Type : Entity_Id) is
begin
- if Present (Subt)
- and then (not Covers (Base_Type ((Bas)), Comp_Type)
+ if not Present (Subt) then
+ return;
+ end if;
+
+ if Is_Anonymous_Access_Type (Entity (Subt)) then
+ if not Is_Anonymous_Access_Type (Comp_Type) then
+ Error_Msg_NE
+ ("component type& is not an anonymous access",
+ Subt, Comp_Type);
+
+ elsif not Conforming_Types
+ (Designated_Type (Entity (Subt)),
+ Designated_Type (Comp_Type),
+ Fully_Conformant)
+ then
+ Error_Msg_NE
+ ("subtype indication does not match component type&",
+ Subt, Comp_Type);
+ end if;
+
+ elsif Present (Subt)
+ and then (not Covers (Base_Type (Bas), Comp_Type)
or else not Subtypes_Statically_Match (Bas, Comp_Type))
then
if Is_Array_Type (Typ) then
- Error_Msg_N
- ("subtype indication does not match component type", Subt);
+ Error_Msg_NE
+ ("subtype indication does not match component type&",
+ Subt, Comp_Type);
else
- Error_Msg_N
- ("subtype indication does not match element type", Subt);
+ Error_Msg_NE
+ ("subtype indication does not match element type&",
+ Subt, Comp_Type);
end if;
end if;
- end Check_Subtype_Indication;
+ end Check_Subtype_Definition;
---------------------
-- Get_Cursor_Type --
@@ -2202,6 +2312,39 @@ package body Sem_Ch5 is
Analyze (Decl);
Rewrite (Subt, New_Occurrence_Of (S, Sloc (Subt)));
end;
+
+ -- Ada 2022: the subtype definition may be for an anonymous
+ -- access type.
+
+ elsif Nkind (Subt) = N_Access_Definition then
+ declare
+ S : constant Entity_Id := Make_Temporary (Sloc (Subt), 'S');
+ Decl : Node_Id;
+ begin
+ if Present (Subtype_Mark (Subt)) then
+ Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => S,
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present => True,
+ Subtype_Indication =>
+ New_Copy_Tree (Subtype_Mark (Subt))));
+
+ else
+ Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => S,
+ Type_Definition =>
+ New_Copy_Tree
+ (Access_To_Subprogram_Definition (Subt)));
+ end if;
+
+ Insert_Before (Parent (Parent (N)), Decl);
+ Analyze (Decl);
+ Freeze_Before (First (Statements (Parent (Parent (N)))), S);
+ Rewrite (Subt, New_Occurrence_Of (S, Sloc (Subt)));
+ end;
else
Analyze (Subt);
end if;
@@ -2479,7 +2622,7 @@ package body Sem_Ch5 is
& "component of a mutable object", N);
end if;
- Check_Subtype_Indication (Component_Type (Typ));
+ Check_Subtype_Definition (Component_Type (Typ));
-- Here we have a missing Range attribute
@@ -2529,7 +2672,7 @@ package body Sem_Ch5 is
end if;
end;
- Check_Subtype_Indication (Etype (Def_Id));
+ Check_Subtype_Definition (Etype (Def_Id));
-- For a predefined container, the type of the loop variable is
-- the Iterator_Element aspect of the container type.
@@ -2556,7 +2699,7 @@ package body Sem_Ch5 is
Cursor_Type := Get_Cursor_Type (Typ);
pragma Assert (Present (Cursor_Type));
- Check_Subtype_Indication (Etype (Def_Id));
+ Check_Subtype_Definition (Etype (Def_Id));
-- If the container has a variable indexing aspect, the
-- element is a variable and is modifiable in the loop.
@@ -3377,6 +3520,32 @@ package body Sem_Ch5 is
("\loop executes zero times or raises "
& "Constraint_Error??", Bad_Bound);
end if;
+
+ if Compile_Time_Compare (LLo, LHi, Assume_Valid => False)
+ = GT
+ then
+ Error_Msg_N ("??constrained range is null",
+ Constraint (DS));
+
+ -- Additional constraints on modular types can be
+ -- confusing, add more information.
+
+ if Ekind (Etype (DS)) = E_Modular_Integer_Subtype then
+ Error_Msg_Uint_1 := Intval (LLo);
+ Error_Msg_Uint_2 := Intval (LHi);
+ Error_Msg_NE ("\iterator has modular type &, " &
+ "so the loop has bounds ^ ..^",
+ Constraint (DS),
+ Subtype_Mark (DS));
+ end if;
+
+ Set_Is_Null_Loop (Loop_Nod);
+ Null_Range := True;
+
+ -- Suppress other warnigns about the body of the loop, as
+ -- it will never execute.
+ Set_Suppress_Loop_Warnings (Loop_Nod);
+ end if;
end;
end if;
@@ -4064,11 +4233,67 @@ package body Sem_Ch5 is
-------------------------
procedure Analyze_Target_Name (N : Node_Id) is
+ procedure Report_Error;
+ -- Complain about illegal use of target_name and rewrite it into unknown
+ -- identifier.
+
+ ------------------
+ -- Report_Error --
+ ------------------
+
+ procedure Report_Error is
+ begin
+ Error_Msg_N
+ ("must appear in the right-hand side of an assignment statement",
+ N);
+ Rewrite (N, New_Occurrence_Of (Any_Id, Sloc (N)));
+ end Report_Error;
+
+ -- Start of processing for Analyze_Target_Name
+
begin
-- A target name has the type of the left-hand side of the enclosing
-- assignment.
- Set_Etype (N, Etype (Name (Current_Assignment)));
+ -- First, verify that the context is the right-hand side of an
+ -- assignment statement.
+
+ if No (Current_Assignment) then
+ Report_Error;
+ return;
+ end if;
+
+ declare
+ Current : Node_Id := N;
+ Context : Node_Id := Parent (N);
+ begin
+ while Present (Context) loop
+
+ -- Check if target_name appears in the expression of the enclosing
+ -- assignment.
+
+ if Nkind (Context) = N_Assignment_Statement then
+ if Current = Expression (Context) then
+ pragma Assert (Context = Current_Assignment);
+ Set_Etype (N, Etype (Name (Current_Assignment)));
+ else
+ Report_Error;
+ end if;
+ return;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (Context) then
+ Report_Error;
+ return;
+ end if;
+
+ Current := Context;
+ Context := Parent (Context);
+ end loop;
+
+ Report_Error;
+ end;
end Analyze_Target_Name;
------------------------
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index c361acc..304dc19 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -36,7 +36,6 @@ with Errout; use Errout;
with Expander; use Expander;
with Exp_Ch3; use Exp_Ch3;
with Exp_Ch6; use Exp_Ch6;
-with Exp_Ch7; use Exp_Ch7;
with Exp_Ch9; use Exp_Ch9;
with Exp_Dbug; use Exp_Dbug;
with Exp_Tss; use Exp_Tss;
@@ -299,8 +298,9 @@ package body Sem_Ch6 is
Asp : Node_Id;
New_Body : Node_Id;
New_Spec : Node_Id;
- Orig_N : Node_Id;
+ Orig_N : Node_Id := Empty;
Ret : Node_Id;
+ Typ : Entity_Id := Empty;
Def_Id : Entity_Id := Empty;
Prev : Entity_Id;
@@ -334,6 +334,8 @@ package body Sem_Ch6 is
Def_Id := Analyze_Subprogram_Specification (Spec);
Prev := Find_Corresponding_Spec (N);
+ Typ := Etype (Def_Id);
+
-- The previous entity may be an expression function as well, in
-- which case the redeclaration is illegal.
@@ -407,7 +409,7 @@ package body Sem_Ch6 is
if not Inside_A_Generic then
Freeze_Expr_Types
(Def_Id => Def_Id,
- Typ => Etype (Def_Id),
+ Typ => Typ,
Expr => Expr,
N => N);
end if;
@@ -497,6 +499,8 @@ package body Sem_Ch6 is
Def_Id := Defining_Entity (N);
Set_Is_Inlined (Def_Id);
+ Typ := Etype (Def_Id);
+
-- Establish the linkages between the spec and the body. These are
-- used when the expression function acts as the prefix of attribute
-- 'Access in order to freeze the original expression which has been
@@ -518,107 +522,99 @@ package body Sem_Ch6 is
Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id));
Push_Scope (Def_Id);
Install_Formals (Def_Id);
- Preanalyze_Spec_Expression (Expr, Etype (Def_Id));
+ Preanalyze_Spec_Expression (Expr, Typ);
+ End_Scope;
+ else
+ Push_Scope (Def_Id);
+ Install_Formals (Def_Id);
+ Preanalyze_Formal_Expression (Expr, Typ);
+ Check_Limited_Return (Orig_N, Expr, Typ);
End_Scope;
end if;
+ -- If this is a wrapper created in an instance for a formal
+ -- subprogram, insert body after declaration, to be analyzed when the
+ -- enclosing instance is analyzed.
+
+ if GNATprove_Mode
+ and then Is_Generic_Actual_Subprogram (Def_Id)
+ then
+ Insert_After (N, New_Body);
+
-- To prevent premature freeze action, insert the new body at the end
-- of the current declarations, or at the end of the package spec.
-- However, resolve usage names now, to prevent spurious visibility
-- on later entities. Note that the function can now be called in
- -- the current declarative part, which will appear to be prior to
- -- the presence of the body in the code. There are nevertheless no
- -- order of elaboration issues because all name resolution has taken
- -- place at the point of declaration.
-
- declare
- Decls : List_Id := List_Containing (N);
- Expr : constant Node_Id := Expression (Ret);
- Par : constant Node_Id := Parent (Decls);
- Typ : constant Entity_Id := Etype (Def_Id);
-
- begin
- -- If this is a wrapper created for in an instance for a formal
- -- subprogram, insert body after declaration, to be analyzed when
- -- the enclosing instance is analyzed.
+ -- the current declarative part, which will appear to be prior to the
+ -- presence of the body in the code. There are nevertheless no order
+ -- of elaboration issues because all name resolution has taken place
+ -- at the point of declaration.
- if GNATprove_Mode
- and then Is_Generic_Actual_Subprogram (Def_Id)
- then
- Insert_After (N, New_Body);
+ else
+ declare
+ Decls : List_Id := List_Containing (N);
+ Par : constant Node_Id := Parent (Decls);
- else
+ begin
if Nkind (Par) = N_Package_Specification
and then Decls = Visible_Declarations (Par)
- and then Present (Private_Declarations (Par))
and then not Is_Empty_List (Private_Declarations (Par))
then
Decls := Private_Declarations (Par);
end if;
Insert_After (Last (Decls), New_Body);
+ end;
+ end if;
- -- Preanalyze the expression if not already done above
-
- if not Inside_A_Generic then
- Push_Scope (Def_Id);
- Install_Formals (Def_Id);
- Preanalyze_Formal_Expression (Expr, Typ);
- Check_Limited_Return (Original_Node (N), Expr, Typ);
- End_Scope;
- end if;
-
- -- In the case of an expression function marked with the
- -- aspect Static, we need to check the requirement that the
- -- function's expression is a potentially static expression.
- -- This is done by making a full copy of the expression tree
- -- and performing a special preanalysis on that tree with
- -- the global flag Checking_Potentially_Static_Expression
- -- enabled. If the resulting expression is static, then it's
- -- OK, but if not, that means the expression violates the
- -- requirements of the Ada 2022 RM in 4.9(3.2/5-3.4/5) and
- -- we flag an error.
-
- if Is_Static_Function (Def_Id) then
- if not Is_Static_Expression (Expr) then
- declare
- Exp_Copy : constant Node_Id := New_Copy_Tree (Expr);
- begin
- Set_Checking_Potentially_Static_Expression (True);
+ -- In the case of an expression function marked with the aspect
+ -- Static, we need to check the requirement that the function's
+ -- expression is a potentially static expression. This is done
+ -- by making a full copy of the expression tree and performing
+ -- a special preanalysis on that tree with the global flag
+ -- Checking_Potentially_Static_Expression enabled. If the
+ -- resulting expression is static, then it's OK, but if not, that
+ -- means the expression violates the requirements of the Ada 2022
+ -- RM in 4.9(3.2/5-3.4/5) and we flag an error.
- Preanalyze_Formal_Expression (Exp_Copy, Typ);
+ if Is_Static_Function (Def_Id) then
+ if not Is_Static_Expression (Expr) then
+ declare
+ Exp_Copy : constant Node_Id := New_Copy_Tree (Expr);
+ begin
+ Set_Checking_Potentially_Static_Expression (True);
- if not Is_Static_Expression (Exp_Copy) then
- Error_Msg_N
- ("static expression function requires "
- & "potentially static expression", Expr);
- end if;
+ Preanalyze_Formal_Expression (Exp_Copy, Typ);
- Set_Checking_Potentially_Static_Expression (False);
- end;
+ if not Is_Static_Expression (Exp_Copy) then
+ Error_Msg_N
+ ("static expression function requires "
+ & "potentially static expression", Expr);
end if;
- -- We also make an additional copy of the expression and
- -- replace the expression of the expression function with
- -- this copy, because the currently present expression is
- -- now associated with the body created for the static
- -- expression function, which will later be analyzed and
- -- possibly rewritten, and we need to have the separate
- -- unanalyzed copy available for use with later static
- -- calls.
+ Set_Checking_Potentially_Static_Expression (False);
+ end;
+ end if;
- Set_Expression
- (Original_Node (Subprogram_Spec (Def_Id)),
- New_Copy_Tree (Expr));
+ -- We also make an additional copy of the expression and
+ -- replace the expression of the expression function with
+ -- this copy, because the currently present expression is
+ -- now associated with the body created for the static
+ -- expression function, which will later be analyzed and
+ -- possibly rewritten, and we need to have the separate
+ -- unanalyzed copy available for use with later static
+ -- calls.
- -- Mark static expression functions as inlined, to ensure
- -- that even calls with nonstatic actuals will be inlined.
+ Set_Expression
+ (Original_Node (Subprogram_Spec (Def_Id)),
+ New_Copy_Tree (Expr));
- Set_Has_Pragma_Inline (Def_Id);
- Set_Is_Inlined (Def_Id);
- end if;
- end if;
- end;
+ -- Mark static expression functions as inlined, to ensure
+ -- that even calls with nonstatic actuals will be inlined.
+
+ Set_Has_Pragma_Inline (Def_Id);
+ Set_Is_Inlined (Def_Id);
+ end if;
end if;
-- Check incorrect use of dynamically tagged expression. This doesn't
@@ -627,13 +623,12 @@ package body Sem_Ch6 is
-- nodes that don't come from source.
if Present (Def_Id)
- and then Nkind (Def_Id) in N_Has_Etype
- and then Is_Tagged_Type (Etype (Def_Id))
+ and then Is_Tagged_Type (Typ)
then
Check_Dynamically_Tagged_Expression
(Expr => Expr,
- Typ => Etype (Def_Id),
- Related_Nod => Original_Node (N));
+ Typ => Typ,
+ Related_Nod => Orig_N);
end if;
-- We must enforce checks for unreferenced formals in our newly
@@ -643,9 +638,9 @@ package body Sem_Ch6 is
if Present (Parameter_Specifications (New_Spec)) then
declare
Form_New_Def : Entity_Id;
- Form_New_Spec : Entity_Id;
+ Form_New_Spec : Node_Id;
Form_Old_Def : Entity_Id;
- Form_Old_Spec : Entity_Id;
+ Form_Old_Spec : Node_Id;
begin
Form_New_Spec := First (Parameter_Specifications (New_Spec));
@@ -3459,7 +3454,12 @@ package body Sem_Ch6 is
-- Link the body and the generated spec
Set_Corresponding_Body (Decl, Body_Id);
- Set_Corresponding_Spec (N, Subp);
+
+ if Nkind (N) = N_Subprogram_Body_Stub then
+ Set_Corresponding_Spec_Of_Stub (N, Subp);
+ else
+ Set_Corresponding_Spec (N, Subp);
+ end if;
Set_Defining_Unit_Name (Specification (Decl), Subp);
@@ -4586,6 +4586,17 @@ package body Sem_Ch6 is
then
Conformant := True;
+ -- Finally, a body generated for an expression function copies
+ -- the profile of the function and no check is needed either.
+ -- If the body is the completion of a previous function
+ -- declared elsewhere, the conformance check is required.
+
+ elsif Nkind (N) = N_Subprogram_Body
+ and then Was_Expression_Function (N)
+ and then Sloc (Spec_Id) = Sloc (Body_Id)
+ then
+ Conformant := True;
+
else
Check_Conformance
(Body_Id, Spec_Id,
@@ -6748,18 +6759,7 @@ package body Sem_Ch6 is
-- may not be known yet (for private types).
if not Has_Delayed_Freeze (Designator) and then Expander_Active then
- declare
- Typ : constant Entity_Id := Etype (Designator);
- Utyp : constant Entity_Id := Underlying_Type (Typ);
-
- begin
- if Is_Limited_View (Typ) then
- Set_Returns_By_Ref (Designator);
-
- elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
- Set_Returns_By_Ref (Designator);
- end if;
- end;
+ Compute_Returns_By_Ref (Designator);
end if;
end Check_Delayed_Subprogram;
@@ -7011,16 +7011,14 @@ package body Sem_Ch6 is
-- A limited interface that is not immutably limited is OK
if Is_Limited_Interface (R_Type)
- and then
- not (Is_Task_Interface (R_Type)
- or else Is_Protected_Interface (R_Type)
- or else Is_Synchronized_Interface (R_Type))
+ and then not Is_Concurrent_Interface (R_Type)
then
null;
elsif Is_Limited_Type (R_Type)
and then not Is_Interface (R_Type)
- and then Comes_From_Source (N)
+ and then not (Nkind (N) = N_Simple_Return_Statement
+ and then Comes_From_Extended_Return_Statement (N))
and then not In_Instance_Body
and then not OK_For_Limited_Init_In_05 (R_Type, Expr)
then
@@ -8904,7 +8902,7 @@ package body Sem_Ch6 is
end if;
if not Has_Discriminants (Formal_Type)
- and then Ekind (Formal_Type) in Private_Kind
+ and then Is_Private_Type (Formal_Type)
and then Present (Underlying_Type (Formal_Type))
then
Formal_Type := Underlying_Type (Formal_Type);
@@ -11021,9 +11019,11 @@ package body Sem_Ch6 is
(Is_Primitive : out Boolean;
Is_Overriding : Boolean := False)
is
- Formal : Entity_Id;
- F_Typ : Entity_Id;
- B_Typ : Entity_Id;
+ procedure Add_Or_Replace_Untagged_Primitive (Typ : Entity_Id);
+ -- Either add the new subprogram to the list of primitives for
+ -- untagged type Typ, or if it overrides a primitive of Typ, then
+ -- replace the overridden primitive in Typ's primitives list with
+ -- the new subprogram.
function Visible_Part_Type (T : Entity_Id) return Boolean;
-- Returns true if T is declared in the visible part of the current
@@ -11038,6 +11038,63 @@ package body Sem_Ch6 is
-- in a private part, then it must override a function declared in
-- the visible part.
+ ---------------------------------------
+ -- Add_Or_Replace_Untagged_Primitive --
+ ---------------------------------------
+
+ procedure Add_Or_Replace_Untagged_Primitive (Typ : Entity_Id) is
+ Replaced_Overridden_Subp : Boolean := False;
+
+ begin
+ pragma Assert (not Is_Tagged_Type (Typ));
+
+ -- Anonymous access types don't have a primitives list. Normally
+ -- such types wouldn't make it here, but the case of anonymous
+ -- access-to-subprogram types can.
+
+ if not Is_Anonymous_Access_Type (Typ) then
+
+ -- If S overrides a subprogram that's a primitive of
+ -- the formal's type, then replace the overridden
+ -- subprogram with the new subprogram in the type's
+ -- list of primitives.
+
+ if Is_Overriding then
+ pragma Assert (Present (Overridden_Subp)
+ and then Overridden_Subp = E); -- Added for now
+
+ declare
+ Prim_Ops : constant Elist_Id :=
+ Primitive_Operations (Typ);
+ Elmt : Elmt_Id;
+ begin
+ if Present (Prim_Ops) then
+ Elmt := First_Elmt (Prim_Ops);
+
+ while Present (Elmt)
+ and then Node (Elmt) /= Overridden_Subp
+ loop
+ Next_Elmt (Elmt);
+ end loop;
+
+ if Present (Elmt) then
+ Replace_Elmt (Elmt, S);
+ Replaced_Overridden_Subp := True;
+ end if;
+ end if;
+ end;
+ end if;
+
+ -- If the new subprogram did not override an operation
+ -- of the formal's type, then add it to the primitives
+ -- list of the type.
+
+ if not Replaced_Overridden_Subp then
+ Append_Unique_Elmt (S, Primitive_Operations (Typ));
+ end if;
+ end if;
+ end Add_Or_Replace_Untagged_Primitive;
+
------------------------------
-- Check_Private_Overriding --
------------------------------
@@ -11193,7 +11250,7 @@ package body Sem_Ch6 is
-- If the entity is a private type, then it must be declared in a
-- visible part.
- if Ekind (T) in Private_Kind then
+ if Is_Private_Type (T) then
return True;
elsif Is_Type (T) and then Has_Private_Declaration (T) then
@@ -11210,13 +11267,29 @@ package body Sem_Ch6 is
end if;
end Visible_Part_Type;
+ -- Local variables
+
+ Formal : Entity_Id;
+ F_Typ : Entity_Id;
+ B_Typ : Entity_Id;
+
-- Start of processing for Check_For_Primitive_Subprogram
begin
Is_Primitive := False;
if not Comes_From_Source (S) then
- null;
+
+ -- Add an inherited primitive for an untagged derived type to
+ -- Derived_Type's list of primitives. Tagged primitives are dealt
+ -- with in Check_Dispatching_Operation.
+
+ if Present (Derived_Type)
+ and then Extensions_Allowed
+ and then not Is_Tagged_Type (Derived_Type)
+ then
+ Append_Unique_Elmt (S, Primitive_Operations (Derived_Type));
+ end if;
-- If subprogram is at library level, it is not primitive operation
@@ -11245,8 +11318,18 @@ package body Sem_Ch6 is
Is_Primitive := True;
Set_Has_Primitive_Operations (B_Typ);
Set_Is_Primitive (S);
- Check_Private_Overriding (B_Typ);
+ -- Add a primitive for an untagged type to B_Typ's list
+ -- of primitives. Tagged primitives are dealt with in
+ -- Check_Dispatching_Operation.
+
+ if Extensions_Allowed
+ and then not Is_Tagged_Type (B_Typ)
+ then
+ Add_Or_Replace_Untagged_Primitive (B_Typ);
+ end if;
+
+ Check_Private_Overriding (B_Typ);
-- The Ghost policy in effect at the point of declaration
-- or a tagged type and a primitive operation must match
-- (SPARK RM 6.9(16)).
@@ -11278,6 +11361,17 @@ package body Sem_Ch6 is
Is_Primitive := True;
Set_Is_Primitive (S);
Set_Has_Primitive_Operations (B_Typ);
+
+ -- Add a primitive for an untagged type to B_Typ's list
+ -- of primitives. Tagged primitives are dealt with in
+ -- Check_Dispatching_Operation.
+
+ if Extensions_Allowed
+ and then not Is_Tagged_Type (B_Typ)
+ then
+ Add_Or_Replace_Untagged_Primitive (B_Typ);
+ end if;
+
Check_Private_Overriding (B_Typ);
-- The Ghost policy in effect at the point of declaration
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index 69ad184..f30a9aa 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -2612,6 +2612,15 @@ package body Sem_Ch7 is
elsif Abstract_Present (Def) then
Error_Msg_N ("only a tagged type can be abstract", N);
+
+ -- When extensions are enabled, we initialize the primitive operations
+ -- list of an untagged private type to an empty element list. (Note:
+ -- This could be done for all private types and shared with the tagged
+ -- case above, but for now we do it separately when the feature of
+ -- prefixed calls for untagged types is enabled.)
+
+ elsif Extensions_Allowed then
+ Set_Direct_Primitive_Operations (Id, New_Elmt_List);
end if;
end New_Private_Type;
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index aa33c50..78d2426 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -3790,15 +3790,31 @@ package body Sem_Ch8 is
Set_Has_Delayed_Freeze (New_S, False);
Freeze_Before (N, New_S);
- -- An abstract subprogram is only allowed as an actual in the case
- -- where the formal subprogram is also abstract.
-
if (Ekind (Old_S) = E_Procedure or else Ekind (Old_S) = E_Function)
- and then Is_Abstract_Subprogram (Old_S)
and then not Is_Abstract_Subprogram (Formal_Spec)
then
- Error_Msg_N
- ("abstract subprogram not allowed as generic actual", Nam);
+ -- An abstract subprogram is only allowed as an actual in the
+ -- case where the formal subprogram is also abstract.
+
+ if Is_Abstract_Subprogram (Old_S) then
+ Error_Msg_N
+ ("abstract subprogram not allowed as generic actual", Nam);
+ end if;
+
+ -- AI12-0412: A primitive of an abstract type with Pre'Class
+ -- or Post'Class aspects specified with nonstatic expressions
+ -- is not allowed as actual for a nonabstract formal subprogram
+ -- (see RM 6.1.1(18.2/5).
+
+ if Is_Dispatching_Operation (Old_S)
+ and then
+ Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Old_S)
+ then
+ Error_Msg_N
+ ("primitive of abstract type with nonstatic class-wide "
+ & "pre/postconditions not allowed as actual",
+ Nam);
+ end if;
end if;
end if;
@@ -7588,10 +7604,16 @@ package body Sem_Ch8 is
P_Type := Implicitly_Designated_Type (P_Type);
end if;
- -- First check for components of a record object (not the
- -- result of a call, which is handled below).
+ -- First check for components of a record object (not the result of
+ -- a call, which is handled below). This also covers the case where
+ -- where the extension feature that supports the prefixed form of
+ -- calls for primitives of untagged types is enabled (excluding
+ -- concurrent cases, which are handled further below).
- if Has_Components (P_Type)
+ if Is_Type (P_Type)
+ and then (Has_Components (P_Type)
+ or else (Extensions_Allowed
+ and then not Is_Concurrent_Type (P_Type)))
and then not Is_Overloadable (P_Name)
and then not Is_Type (P_Name)
then
@@ -8989,6 +9011,28 @@ package body Sem_Ch8 is
procedure Push_Scope (S : Entity_Id) is
E : constant Entity_Id := Scope (S);
+ function Component_Alignment_Default return Component_Alignment_Kind;
+ -- Return Component_Alignment_Kind for the newly-pushed scope.
+
+ function Component_Alignment_Default return Component_Alignment_Kind is
+ begin
+ -- Each new scope pushed onto the scope stack inherits the component
+ -- alignment of the previous scope. This emulates the "visibility"
+ -- semantics of pragma Component_Alignment.
+
+ if Scope_Stack.Last > Scope_Stack.First then
+ return Scope_Stack.Table
+ (Scope_Stack.Last - 1).Component_Alignment_Default;
+
+ -- Otherwise, this is the first scope being pushed on the scope
+ -- stack. Inherit the component alignment from the configuration
+ -- form of pragma Component_Alignment (if any).
+
+ else
+ return Configuration_Component_Alignment;
+ end if;
+ end Component_Alignment_Default;
+
begin
if Ekind (S) = E_Void then
null;
@@ -9017,49 +9061,27 @@ package body Sem_Ch8 is
Scope_Stack.Increment_Last;
- declare
- SST : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
-
- begin
- SST.Entity := S;
- SST.Save_Scope_Suppress := Scope_Suppress;
- SST.Save_Local_Suppress_Stack_Top := Local_Suppress_Stack_Top;
- SST.Save_Check_Policy_List := Check_Policy_List;
- SST.Save_Default_Storage_Pool := Default_Pool;
- SST.Save_No_Tagged_Streams := No_Tagged_Streams;
- SST.Save_SPARK_Mode := SPARK_Mode;
- SST.Save_SPARK_Mode_Pragma := SPARK_Mode_Pragma;
- SST.Save_Default_SSO := Default_SSO;
- SST.Save_Uneval_Old := Uneval_Old;
-
- -- Each new scope pushed onto the scope stack inherits the component
- -- alignment of the previous scope. This emulates the "visibility"
- -- semantics of pragma Component_Alignment.
-
- if Scope_Stack.Last > Scope_Stack.First then
- SST.Component_Alignment_Default :=
- Scope_Stack.Table
- (Scope_Stack.Last - 1).Component_Alignment_Default;
-
- -- Otherwise, this is the first scope being pushed on the scope
- -- stack. Inherit the component alignment from the configuration
- -- form of pragma Component_Alignment (if any).
-
- else
- SST.Component_Alignment_Default :=
- Configuration_Component_Alignment;
- end if;
-
- SST.Last_Subprogram_Name := null;
- SST.Is_Transient := False;
- SST.Node_To_Be_Wrapped := Empty;
- SST.Pending_Freeze_Actions := No_List;
- SST.Actions_To_Be_Wrapped := (others => No_List);
- SST.First_Use_Clause := Empty;
- SST.Is_Active_Stack_Base := False;
- SST.Previous_Visibility := False;
- SST.Locked_Shared_Objects := No_Elist;
- end;
+ Scope_Stack.Table (Scope_Stack.Last) :=
+ (Entity => S,
+ Save_Scope_Suppress => Scope_Suppress,
+ Save_Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
+ Save_Check_Policy_List => Check_Policy_List,
+ Save_Default_Storage_Pool => Default_Pool,
+ Save_No_Tagged_Streams => No_Tagged_Streams,
+ Save_SPARK_Mode => SPARK_Mode,
+ Save_SPARK_Mode_Pragma => SPARK_Mode_Pragma,
+ Save_Default_SSO => Default_SSO,
+ Save_Uneval_Old => Uneval_Old,
+ Component_Alignment_Default => Component_Alignment_Default,
+ Last_Subprogram_Name => null,
+ Is_Transient => False,
+ Node_To_Be_Wrapped => Empty,
+ Pending_Freeze_Actions => No_List,
+ Actions_To_Be_Wrapped => (others => No_List),
+ First_Use_Clause => Empty,
+ Is_Active_Stack_Base => False,
+ Previous_Visibility => False,
+ Locked_Shared_Objects => No_Elist);
if Debug_Flag_W then
Write_Str ("--> new scope: ");
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index 969eff5..ab25dd0 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -1955,9 +1955,7 @@ package body Sem_Ch9 is
Tasking_Used := True;
Analyze_Declarations (Visible_Declarations (N));
- if Present (Private_Declarations (N))
- and then not Is_Empty_List (Private_Declarations (N))
- then
+ if not Is_Empty_List (Private_Declarations (N)) then
Last_Id := Last_Entity (Prot_Typ);
Analyze_Declarations (Private_Declarations (N));
@@ -2031,6 +2029,12 @@ package body Sem_Ch9 is
Set_Has_Delayed_Freeze (T);
Set_Stored_Constraint (T, No_Elist);
+ -- Initialize type's primitive operations list, for possible use when
+ -- the extension of prefixed call notation for untagged types is enabled
+ -- (such as by use of -gnatX).
+
+ Set_Direct_Primitive_Operations (T, New_Elmt_List);
+
-- Mark this type as a protected type for the sake of restrictions,
-- unless the protected type is declared in a private part of a package
-- of the runtime. With this exception, the Suspension_Object from
@@ -3152,6 +3156,12 @@ package body Sem_Ch9 is
Set_Has_Delayed_Freeze (T, True);
Set_Stored_Constraint (T, No_Elist);
+ -- Initialize type's primitive operations list, for possible use when
+ -- the extension of prefixed call notation for untagged types is enabled
+ -- (such as by use of -gnatX).
+
+ Set_Direct_Primitive_Operations (T, New_Elmt_List);
+
-- Set the SPARK_Mode from the current context (may be overwritten later
-- with an explicit pragma).
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 15b700fa..064e2b5 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -45,7 +45,6 @@ with Restrict; use Restrict;
with Rident; use Rident;
with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
-with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Eval; use Sem_Eval;
@@ -613,29 +612,32 @@ package body Sem_Disp is
Set_Entity (Name (N), Alias (Subp));
return;
- -- An obscure special case: a null procedure may have a class-
- -- wide pre/postcondition that includes a call to an abstract
- -- subp. Calls within the expression may not have been rewritten
- -- as dispatching calls yet, because the null body appears in
- -- the current declarative part. The expression will be properly
- -- rewritten/reanalyzed when the postcondition procedure is built.
-
- -- Similarly, if this is a pre/postcondition for an abstract
- -- subprogram, it may call another abstract function which is
- -- a primitive of an abstract type. The call is non-dispatching
- -- but will be legal in overridings of the operation. However,
- -- if the call is tag-indeterminate we want to continue with
- -- with the error checking below, as this case is illegal even
- -- for abstract subprograms (see AI12-0170).
-
- elsif (Is_Subprogram (Scop)
- or else Chars (Scop) = Name_Postcondition)
+ -- If this is a pre/postcondition for an abstract subprogram,
+ -- it may call another abstract function that is a primitive
+ -- of an abstract type. The call is nondispatching but will be
+ -- legal in overridings of the operation. However, if the call
+ -- is tag-indeterminate we want to continue with with the error
+ -- checking below, as this case is illegal even for abstract
+ -- subprograms (see AI12-0170).
+
+ -- Similarly, as per AI12-0412, a nonabstract subprogram may
+ -- have a class-wide pre/postcondition that includes a call to
+ -- an abstract primitive of the subprogram's controlling type.
+ -- Certain operations (nondispatching calls, 'Access, use as
+ -- a generic actual) applied to such a nonabstract subprogram
+ -- are illegal in the case where the type is abstract (see
+ -- RM 6.1.1(18.2/5)).
+
+ elsif Is_Subprogram (Scop)
+ and then not Is_Tag_Indeterminate (N)
+ and then In_Pre_Post_Condition (Call, Class_Wide_Only => True)
+
+ -- The tagged type associated with the called subprogram must be
+ -- the same as that of the subprogram with a class-wide aspect.
+
+ and then Is_Dispatching_Operation (Scop)
and then
- ((Is_Abstract_Subprogram (Scop)
- and then not Is_Tag_Indeterminate (N))
- or else
- (Nkind (Parent (Scop)) = N_Procedure_Specification
- and then Null_Present (Parent (Scop))))
+ Find_Dispatching_Type (Subp) = Find_Dispatching_Type (Scop)
then
null;
@@ -664,7 +666,7 @@ package body Sem_Disp is
-- provides a tag to make the call dispatching. This requires
-- the call to be the actual in an enclosing call, and that
-- actual must be controlling. If the call is an operand of
- -- equality, the other operand must not ve abstract.
+ -- equality, the other operand must not be abstract.
if not Is_Tagged_Type (Typ)
and then not
@@ -971,7 +973,6 @@ package body Sem_Disp is
end loop;
Check_Dispatching_Context (N);
- return;
elsif Nkind (Parent (N)) in N_Subexpr then
Check_Dispatching_Context (N);
@@ -986,6 +987,23 @@ package body Sem_Disp is
return;
end if;
+ -- If this is a nondispatching call to a nonabstract subprogram
+ -- and the subprogram has any Pre'Class or Post'Class aspects with
+ -- nonstatic values, then report an error. This is specified by
+ -- RM 6.1.1(18.2/5) (by AI12-0412).
+
+ if No (Control)
+ and then not Is_Abstract_Subprogram (Subp_Entity)
+ and then
+ Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Subp_Entity)
+ then
+ Error_Msg_N
+ ("nondispatching call to nonabstract subprogram of "
+ & "abstract type with nonstatic class-wide "
+ & "pre/postconditions",
+ N);
+ end if;
+
else
-- If dispatching on result, the enclosing call, if any, will
-- determine the controlling argument. Otherwise this is the
@@ -1209,7 +1227,7 @@ package body Sem_Disp is
-- primitives.
-- 3. Subprograms associated with stream attributes (built by
- -- New_Stream_Subprogram)
+ -- New_Stream_Subprogram) or with the Put_Image attribute.
-- 4. Wrappers built for inherited operations with inherited class-
-- wide conditions, where the conditions include calls to other
@@ -1238,6 +1256,7 @@ package body Sem_Disp is
or else Get_TSS_Name (Subp) = TSS_Stream_Read
or else Get_TSS_Name (Subp) = TSS_Stream_Write
+ or else Get_TSS_Name (Subp) = TSS_Put_Image
or else
(Is_Wrapper (Subp)
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 7a70fd8..a3a2864 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -6481,11 +6481,10 @@ package body Sem_Eval is
procedure Set_Checking_Potentially_Static_Expression (Value : Boolean) is
begin
- -- Verify that we're not currently checking for a potentially static
- -- expression unless we're disabling such checking.
+ -- Verify that we only start/stop checking for a potentially static
+ -- expression and do not start or stop it twice in a row.
- pragma Assert
- (not Checking_For_Potentially_Static_Expression or else not Value);
+ pragma Assert (Checking_For_Potentially_Static_Expression /= Value);
Checking_For_Potentially_Static_Expression := Value;
end Set_Checking_Potentially_Static_Expression;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 14351b3..5705aa7 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -1139,6 +1139,17 @@ package body Sem_Prag is
(State_Id => Item_Id,
Ref => Item);
end if;
+
+ elsif Ekind (Item_Id) in E_Constant | E_Variable
+ and then Present (Ultimate_Overlaid_Entity (Item_Id))
+ then
+ SPARK_Msg_NE
+ ("overlaying object & cannot appear in Depends",
+ Item, Item_Id);
+ SPARK_Msg_NE
+ ("\use the overlaid object & instead",
+ Item, Ultimate_Overlaid_Entity (Item_Id));
+ return;
end if;
-- When the item renames an entire object, replace the
@@ -2387,6 +2398,17 @@ package body Sem_Prag is
elsif Is_Formal_Object (Item_Id) then
null;
+ elsif Ekind (Item_Id) in E_Constant | E_Variable
+ and then Present (Ultimate_Overlaid_Entity (Item_Id))
+ then
+ SPARK_Msg_NE
+ ("overlaying object & cannot appear in Global",
+ Item, Item_Id);
+ SPARK_Msg_NE
+ ("\use the overlaid object & instead",
+ Item, Ultimate_Overlaid_Entity (Item_Id));
+ return;
+
-- The only legal references are those to abstract states,
-- objects and various kinds of constants (SPARK RM 6.1.4(4)).
@@ -2433,10 +2455,13 @@ package body Sem_Prag is
SPARK_Msg_N ("\use its constituents instead", Item);
return;
- -- An external state cannot appear as a global item of a
- -- nonvolatile function (SPARK RM 7.1.3(8)).
+ -- An external state which has Async_Writers or
+ -- Effective_Reads enabled cannot appear as a global item
+ -- of a nonvolatile function (SPARK RM 7.1.3(8)).
elsif Is_External_State (Item_Id)
+ and then (Async_Writers_Enabled (Item_Id)
+ or else Effective_Reads_Enabled (Item_Id))
and then Ekind (Spec_Id) in E_Function | E_Generic_Function
and then not Is_Volatile_Function (Spec_Id)
then
@@ -2981,6 +3006,16 @@ package body Sem_Prag is
if Item_Id = Any_Id then
null;
+ elsif Ekind (Item_Id) in E_Constant | E_Variable
+ and then Present (Ultimate_Overlaid_Entity (Item_Id))
+ then
+ SPARK_Msg_NE
+ ("overlaying object & cannot appear in Initializes",
+ Item, Item_Id);
+ SPARK_Msg_NE
+ ("\use the overlaid object & instead",
+ Item, Ultimate_Overlaid_Entity (Item_Id));
+
-- The state or variable must be declared in the visible
-- declarations of the package (SPARK RM 7.1.5(7)).
@@ -3123,6 +3158,18 @@ package body Sem_Prag is
end if;
end if;
+ if Ekind (Input_Id) in E_Constant | E_Variable
+ and then Present (Ultimate_Overlaid_Entity (Input_Id))
+ then
+ SPARK_Msg_NE
+ ("overlaying object & cannot appear in Initializes",
+ Input, Input_Id);
+ SPARK_Msg_NE
+ ("\use the overlaid object & instead",
+ Input, Ultimate_Overlaid_Entity (Input_Id));
+ return;
+ end if;
+
-- Detect a duplicate use of the same input item
-- (SPARK RM 7.1.5(5)).
@@ -10483,6 +10530,41 @@ package body Sem_Prag is
Add_To_Config_Boolean_Restrictions (No_Elaboration_Code);
end if;
+ -- Special processing for No_Dynamic_Accessibility_Checks to
+ -- disallow exclusive specification in a body or subunit.
+
+ elsif R_Id = No_Dynamic_Accessibility_Checks
+ -- Check if the restriction is within configuration pragma
+ -- in a similar way to No_Elaboration_Code.
+
+ and then not (Current_Sem_Unit = Main_Unit
+ or else In_Extended_Main_Source_Unit (N))
+
+ and then Nkind (Unit (Parent (N))) = N_Compilation_Unit
+
+ and then (Nkind (Unit (Parent (N))) = N_Package_Body
+ or else Nkind (Unit (Parent (N))) = N_Subunit)
+
+ and then not Restriction_Active
+ (No_Dynamic_Accessibility_Checks)
+ then
+ Error_Msg_N
+ ("invalid specification of " &
+ """No_Dynamic_Accessibility_Checks""", N);
+
+ if Nkind (Unit (Parent (N))) = N_Package_Body then
+ Error_Msg_N
+ ("\restriction cannot be specified in a package " &
+ "body", N);
+
+ elsif Nkind (Unit (Parent (N))) = N_Subunit then
+ Error_Msg_N
+ ("\restriction cannot be specified in a subunit", N);
+ end if;
+
+ Error_Msg_N
+ ("\unless also specified in spec", N);
+
-- Special processing for No_Tasking restriction (not just a
-- warning) when it appears as a configuration pragma.
@@ -12688,7 +12770,7 @@ package body Sem_Prag is
-- external tool and a tool-specific function. These arguments are
-- not analyzed.
- when Pragma_Annotate => Annotate : declare
+ when Pragma_Annotate | Pragma_GNAT_Annotate => Annotate : declare
Arg : Node_Id;
Expr : Node_Id;
Nam_Arg : Node_Id;
@@ -14656,7 +14738,6 @@ package body Sem_Prag is
-- [, [Link_Name =>] static_string_EXPRESSION ]);
when Pragma_CPP_Constructor => CPP_Constructor : declare
- Elmt : Elmt_Id;
Id : Entity_Id;
Def_Id : Entity_Id;
Tag_Typ : Entity_Id;
@@ -14723,12 +14804,7 @@ package body Sem_Prag is
then
Tag_Typ := Etype (Def_Id);
- Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
- while Present (Elmt) and then Node (Elmt) /= Def_Id loop
- Next_Elmt (Elmt);
- end loop;
-
- Remove_Elmt (Primitive_Operations (Tag_Typ), Elmt);
+ Remove (Primitive_Operations (Tag_Typ), Def_Id);
Set_Is_Dispatching_Operation (Def_Id, False);
end if;
@@ -31246,6 +31322,7 @@ package body Sem_Prag is
Pragma_Finalize_Storage_Only => 0,
Pragma_Ghost => 0,
Pragma_Global => -1,
+ Pragma_GNAT_Annotate => 93,
Pragma_Ident => -1,
Pragma_Ignore_Pragma => 0,
Pragma_Implementation_Defined => -1,
diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads
index c620beb..e166481 100644
--- a/gcc/ada/sem_prag.ads
+++ b/gcc/ada/sem_prag.ads
@@ -63,6 +63,7 @@ package Sem_Prag is
Pragma_Favor_Top_Level => True,
Pragma_Ghost => True,
Pragma_Global => True,
+ Pragma_GNAT_Annotate => True,
Pragma_Import => True,
Pragma_Independent => True,
Pragma_Independent_Components => True,
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index e639fab..03d747e 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -654,9 +654,9 @@ package body Sem_Res is
end if;
end Check_For_Visible_Operator;
- ----------------------------------
- -- Check_Fully_Declared_Prefix --
- ----------------------------------
+ ---------------------------------
+ -- Check_Fully_Declared_Prefix --
+ ---------------------------------
procedure Check_Fully_Declared_Prefix
(Typ : Entity_Id;
@@ -1886,9 +1886,9 @@ package body Sem_Res is
Expander_Mode_Restore;
Full_Analysis := Save_Full_Analysis;
- Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
if not With_Freezing then
+ Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
Inside_Preanalysis_Without_Freezing :=
Inside_Preanalysis_Without_Freezing - 1;
end if;
@@ -2934,6 +2934,11 @@ package body Sem_Res is
else
UI_Image (Norm_Num (Expr_Value_R (Expr)), Decimal);
Start_String;
+
+ if UR_Is_Negative (Expr_Value_R (Expr)) then
+ Store_String_Chars ("-");
+ end if;
+
Store_String_Chars
(UI_Image_Buffer (1 .. UI_Image_Length));
Param1 := Make_String_Literal (Loc, End_String);
@@ -3753,18 +3758,6 @@ package body Sem_Res is
begin
case Nkind (N) is
- when N_Allocator =>
- if not Is_OK_Volatile_Context (Context => Parent (N),
- Obj_Ref => N,
- Check_Actuals => True)
- then
- Error_Msg_N
- ("allocator cannot appear in this context"
- & " (SPARK RM 7.1.3(10))", N);
- end if;
-
- return Skip;
-
-- Do not consider nested function calls because they have
-- already been processed during their own resolution.
@@ -6158,13 +6151,6 @@ package body Sem_Res is
raise Program_Error;
end case;
- -- In GNATprove mode, we enable the division check so that
- -- GNATprove will issue a message if it cannot be proved.
-
- if GNATprove_Mode then
- Activate_Division_Check (N);
- end if;
-
-- Otherwise just set the flag to check at run time
else
@@ -7528,7 +7514,6 @@ package body Sem_Res is
Node := First (Actions (N));
while Present (Node) loop
if Nkind (Node) = N_Object_Declaration
- and then Is_Type (Etype (Defining_Identifier (Node)))
and then Requires_Transient_Scope
(Etype (Defining_Identifier (Node)))
then
@@ -7541,7 +7526,7 @@ package body Sem_Res is
end;
if Need_Transient_Scope then
- Establish_Transient_Scope (Decl, True);
+ Establish_Transient_Scope (Decl, Manage_Sec_Stack => True);
else
Push_Scope (Scope (Defining_Identifier (Decl)));
end if;
@@ -8833,18 +8818,12 @@ package body Sem_Res is
or else Is_Private_Type (T))
then
if Etype (L) /= T then
- Rewrite (L,
- Make_Unchecked_Type_Conversion (Sloc (L),
- Subtype_Mark => New_Occurrence_Of (T, Sloc (L)),
- Expression => Relocate_Node (L)));
+ Rewrite (L, Unchecked_Convert_To (T, L));
Analyze_And_Resolve (L, T);
end if;
if (Etype (R)) /= T then
- Rewrite (R,
- Make_Unchecked_Type_Conversion (Sloc (R),
- Subtype_Mark => New_Occurrence_Of (Etype (L), Sloc (R)),
- Expression => Relocate_Node (R)));
+ Rewrite (R, Unchecked_Convert_To (Etype (L), R));
Analyze_And_Resolve (R, T);
end if;
end if;
@@ -12748,10 +12727,7 @@ package body Sem_Res is
Set_Etype (Array_Subtype, Base_Type (Typ));
Set_Is_Constrained (Array_Subtype, True);
- Rewrite (N,
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Array_Subtype, Loc),
- Expression => Relocate_Node (N)));
+ Rewrite (N, Unchecked_Convert_To (Array_Subtype, N));
Set_Etype (N, Array_Subtype);
end;
end if;
@@ -13688,12 +13664,24 @@ package body Sem_Res is
then
if Is_Itype (Opnd_Type) then
+ -- When applying restriction No_Dynamic_Accessibility_Check,
+ -- implicit conversions are allowed when the operand type is
+ -- not deeper than the target type.
+
+ if No_Dynamic_Accessibility_Checks_Enabled (N) then
+ if Type_Access_Level (Opnd_Type)
+ > Deepest_Type_Access_Level (Target_Type)
+ then
+ Conversion_Error_N
+ ("operand has deeper level than target", Operand);
+ end if;
+
-- Implicit conversions aren't allowed for objects of an
-- anonymous access type, since such objects have nonstatic
-- levels in Ada 2012.
- if Nkind (Associated_Node_For_Itype (Opnd_Type)) =
- N_Object_Declaration
+ elsif Nkind (Associated_Node_For_Itype (Opnd_Type))
+ = N_Object_Declaration
then
Conversion_Error_N
("implicit conversion of stand-alone anonymous "
@@ -13746,12 +13734,16 @@ package body Sem_Res is
-- the target type is anonymous access as well - see RM 3.10.2
-- (10.3/3).
- elsif Type_Access_Level (Opnd_Type) >
- Deepest_Type_Access_Level (Target_Type)
- and then (Nkind (Associated_Node_For_Itype (Opnd_Type)) /=
- N_Function_Specification
- or else Ekind (Target_Type) in
- Anonymous_Access_Kind)
+ -- Note that when the restriction No_Dynamic_Accessibility_Checks
+ -- is in effect wei also want to proceed with the conversion check
+ -- described above.
+
+ elsif Type_Access_Level (Opnd_Type, Assoc_Ent => Operand)
+ > Deepest_Type_Access_Level (Target_Type)
+ and then (Nkind (Associated_Node_For_Itype (Opnd_Type))
+ /= N_Function_Specification
+ or else Ekind (Target_Type) in Anonymous_Access_Kind
+ or else No_Dynamic_Accessibility_Checks_Enabled (N))
-- Check we are not in a return value ???
diff --git a/gcc/ada/sem_type.ads b/gcc/ada/sem_type.ads
index 89fd617..018c283 100644
--- a/gcc/ada/sem_type.ads
+++ b/gcc/ada/sem_type.ads
@@ -243,8 +243,7 @@ package Sem_Type is
-- in the signature of an inherited operation must carry the derived type.
function Is_Subtype_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean;
- -- Checks whether T1 is any subtype of T2 directly or indirectly. Applies
- -- only to scalar subtypes???
+ -- Checks whether T1 is any subtype of T2 directly or indirectly
function Operator_Matches_Spec (Op, New_S : Entity_Id) return Boolean;
-- Used to resolve subprograms renaming operators, and calls to user
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index a543268..5d0aa49 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -177,9 +177,9 @@ package body Sem_Util is
-- "subp:file:line:col", corresponding to the source location of the
-- body of the subprogram.
- ------------------------------
- -- Abstract_Interface_List --
- ------------------------------
+ -----------------------------
+ -- Abstract_Interface_List --
+ -----------------------------
function Abstract_Interface_List (Typ : Entity_Id) return List_Id is
Nod : Node_Id;
@@ -260,7 +260,8 @@ package body Sem_Util is
function Accessibility_Level
(Expr : Node_Id;
Level : Accessibility_Level_Kind;
- In_Return_Context : Boolean := False) return Node_Id
+ In_Return_Context : Boolean := False;
+ Allow_Alt_Model : Boolean := True) return Node_Id
is
Loc : constant Source_Ptr := Sloc (Expr);
@@ -281,6 +282,11 @@ package body Sem_Util is
-- Centralized processing of subprogram calls which may appear in
-- prefix notation.
+ function Typ_Access_Level (Typ : Entity_Id) return Uint
+ is (Type_Access_Level (Typ, Allow_Alt_Model));
+ -- Renaming of Type_Access_Level with Allow_Alt_Model specified to avoid
+ -- passing the parameter specifically in every call.
+
----------------------------------
-- Innermost_Master_Scope_Depth --
----------------------------------
@@ -375,7 +381,7 @@ package body Sem_Util is
(Subprogram_Access_Level (Entity (Name (N))));
else
return Make_Level_Literal
- (Type_Access_Level (Etype (Prefix (Name (N)))));
+ (Typ_Access_Level (Etype (Prefix (Name (N)))));
end if;
-- We ignore coextensions as they cannot be implemented under the
@@ -392,19 +398,40 @@ package body Sem_Util is
-- Named access types have a designated level
if Is_Named_Access_Type (Etype (N)) then
- return Make_Level_Literal (Type_Access_Level (Etype (N)));
+ return Make_Level_Literal (Typ_Access_Level (Etype (N)));
-- Otherwise, the level is dictated by RM 3.10.2 (10.7/3)
else
+ -- Check No_Dynamic_Accessibility_Checks restriction override for
+ -- alternative accessibility model.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (N)
+ and then Is_Anonymous_Access_Type (Etype (N))
+ then
+ -- In the alternative model the level is that of the
+ -- designated type.
+
+ if Debug_Flag_Underscore_B then
+ return Make_Level_Literal (Typ_Access_Level (Etype (N)));
+
+ -- Otherwise the level is that of the subprogram
+
+ else
+ return Make_Level_Literal
+ (Subprogram_Access_Level (Entity (Name (N))));
+ end if;
+ end if;
+
if Nkind (N) = N_Function_Call then
-- Dynamic checks are generated when we are within a return
-- value or we are in a function call within an anonymous
-- access discriminant constraint of a return object (signified
-- by In_Return_Context) on the side of the callee.
- -- So, in this case, return library accessibility level to null
- -- out the check on the side of the caller.
+ -- So, in this case, return accessibility level of the
+ -- enclosing subprogram.
if In_Return_Value (N)
or else In_Return_Context
@@ -414,6 +441,17 @@ package body Sem_Util is
end if;
end if;
+ -- When the call is being dereferenced the level is that of the
+ -- enclosing master of the dereferenced call.
+
+ if Nkind (Parent (N)) in N_Explicit_Dereference
+ | N_Indexed_Component
+ | N_Selected_Component
+ then
+ return Make_Level_Literal
+ (Innermost_Master_Scope_Depth (Expr));
+ end if;
+
-- Find any relevant enclosing parent nodes that designate an
-- object being initialized.
@@ -434,7 +472,7 @@ package body Sem_Util is
and then Is_Named_Access_Type (Etype (Par))
then
return Make_Level_Literal
- (Type_Access_Level (Etype (Par)));
+ (Typ_Access_Level (Etype (Par)));
end if;
-- Jump out when we hit an object declaration or the right-hand
@@ -551,7 +589,7 @@ package body Sem_Util is
if Is_Named_Access_Type (Etype (Pre)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (Pre)));
+ (Typ_Access_Level (Etype (Pre)));
-- Anonymous access types
@@ -616,8 +654,34 @@ package body Sem_Util is
(Scope_Depth (Standard_Standard));
end if;
- return
- New_Occurrence_Of (Get_Dynamic_Accessibility (E), Loc);
+ -- No_Dynamic_Accessibility_Checks restriction override for
+ -- alternative accessibility model.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (E)
+ then
+ -- In the alternative model the level is that of the
+ -- designated type entity's context.
+
+ if Debug_Flag_Underscore_B then
+ return Make_Level_Literal (Typ_Access_Level (Etype (E)));
+
+ -- Otherwise the level depends on the entity's context
+
+ elsif Is_Formal (E) then
+ return Make_Level_Literal
+ (Subprogram_Access_Level
+ (Enclosing_Subprogram (E)));
+ else
+ return Make_Level_Literal
+ (Scope_Depth (Enclosing_Dynamic_Scope (E)));
+ end if;
+ end if;
+
+ -- Return the dynamic level in the normal case
+
+ return New_Occurrence_Of
+ (Get_Dynamic_Accessibility (E), Loc);
-- Initialization procedures have a special extra accessitility
-- parameter associated with the level at which the object
@@ -635,8 +699,19 @@ package body Sem_Util is
-- according to RM 3.10.2 (21).
elsif Is_Type (E) then
- return Make_Level_Literal
- (Type_Access_Level (E) + 1);
+ -- When restriction No_Dynamic_Accessibility_Checks is active
+ -- along with -gnatd_b.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (E)
+ and then Debug_Flag_Underscore_B
+ then
+ return Make_Level_Literal (Typ_Access_Level (E));
+ end if;
+
+ -- Normal path
+
+ return Make_Level_Literal (Typ_Access_Level (E) + 1);
-- Move up the renamed entity if it came from source since
-- expansion may have created a dummy renaming under certain
@@ -651,7 +726,7 @@ package body Sem_Util is
elsif Is_Named_Access_Type (Etype (E)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (E)));
+ (Typ_Access_Level (Etype (E)));
-- When E is a component of the current instance of a
-- protected type, we assume the level to be deeper than that of
@@ -702,7 +777,7 @@ package body Sem_Util is
elsif Is_Named_Access_Type (Etype (Pre)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (Pre)));
+ (Typ_Access_Level (Etype (Pre)));
-- The current expression is a named access type, so there is no
-- reason to look at the prefix. Instead obtain the level of E's
@@ -710,21 +785,44 @@ package body Sem_Util is
elsif Is_Named_Access_Type (Etype (E)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (E)));
+ (Typ_Access_Level (Etype (E)));
- -- A non-discriminant selected component where the component
+ -- A nondiscriminant selected component where the component
-- is an anonymous access type means that its associated
-- level is that of the containing type - see RM 3.10.2 (16).
+ -- Note that when restriction No_Dynamic_Accessibility_Checks is
+ -- in effect we treat discriminant components as regular
+ -- components.
+
elsif Nkind (E) = N_Selected_Component
and then Ekind (Etype (E)) = E_Anonymous_Access_Type
and then Ekind (Etype (Pre)) /= E_Anonymous_Access_Type
- and then not (Nkind (Selector_Name (E)) in N_Has_Entity
- and then Ekind (Entity (Selector_Name (E)))
- = E_Discriminant)
+ and then (not (Nkind (Selector_Name (E)) in N_Has_Entity
+ and then Ekind (Entity (Selector_Name (E)))
+ = E_Discriminant)
+
+ -- The alternative accessibility models both treat
+ -- discriminants as regular components.
+
+ or else (No_Dynamic_Accessibility_Checks_Enabled (E)
+ and then Allow_Alt_Model))
then
+ -- When restriction No_Dynamic_Accessibility_Checks is active
+ -- and -gnatd_b set, the level is that of the designated type.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (E)
+ and then Debug_Flag_Underscore_B
+ then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (E)));
+ end if;
+
+ -- Otherwise proceed normally
+
return Make_Level_Literal
- (Type_Access_Level (Etype (Prefix (E))));
+ (Typ_Access_Level (Etype (Prefix (E))));
-- Similar to the previous case - arrays featuring components of
-- anonymous access components get their corresponding level from
@@ -736,8 +834,21 @@ package body Sem_Util is
and then Ekind (Component_Type (Base_Type (Etype (Pre))))
= E_Anonymous_Access_Type
then
+ -- When restriction No_Dynamic_Accessibility_Checks is active
+ -- and -gnatd_b set, the level is that of the designated type.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (E)
+ and then Debug_Flag_Underscore_B
+ then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (E)));
+ end if;
+
+ -- Otherwise proceed normally
+
return Make_Level_Literal
- (Type_Access_Level (Etype (Prefix (E))));
+ (Typ_Access_Level (Etype (Prefix (E))));
-- The accessibility calculation routine that handles function
-- calls (Function_Call_Level) assumes, in the case the
@@ -785,7 +896,7 @@ package body Sem_Util is
when N_Qualified_Expression =>
if Is_Named_Access_Type (Etype (E)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (E)));
+ (Typ_Access_Level (Etype (E)));
else
return Accessibility_Level (Expression (E));
end if;
@@ -804,7 +915,7 @@ package body Sem_Util is
-- its type.
if Is_Named_Access_Type (Etype (Pre)) then
- return Make_Level_Literal (Type_Access_Level (Etype (Pre)));
+ return Make_Level_Literal (Typ_Access_Level (Etype (Pre)));
-- Otherwise, recurse deeper
@@ -831,7 +942,7 @@ package body Sem_Util is
elsif Is_Named_Access_Type (Etype (E)) then
return Make_Level_Literal
- (Type_Access_Level (Etype (E)));
+ (Typ_Access_Level (Etype (E)));
-- In section RM 3.10.2 (10/4) the accessibility rules for
-- aggregates and value conversions are outlined. Are these
@@ -847,7 +958,7 @@ package body Sem_Util is
-- expression's entity.
when others =>
- return Make_Level_Literal (Type_Access_Level (Etype (E)));
+ return Make_Level_Literal (Typ_Access_Level (Etype (E)));
end case;
end Accessibility_Level;
@@ -1409,13 +1520,14 @@ package body Sem_Util is
-----------------------------------------
procedure Apply_Compile_Time_Constraint_Error
- (N : Node_Id;
- Msg : String;
- Reason : RT_Exception_Code;
- Ent : Entity_Id := Empty;
- Typ : Entity_Id := Empty;
- Loc : Source_Ptr := No_Location;
- Warn : Boolean := False)
+ (N : Node_Id;
+ Msg : String;
+ Reason : RT_Exception_Code;
+ Ent : Entity_Id := Empty;
+ Typ : Entity_Id := Empty;
+ Loc : Source_Ptr := No_Location;
+ Warn : Boolean := False;
+ Emit_Message : Boolean := True)
is
Stat : constant Boolean := Is_Static_Expression (N);
R_Stat : constant Node_Id :=
@@ -1429,18 +1541,9 @@ package body Sem_Util is
Rtyp := Typ;
end if;
- Discard_Node
- (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
-
- -- In GNATprove mode, do not replace the node with an exception raised.
- -- In such a case, either the call to Compile_Time_Constraint_Error
- -- issues an error which stops analysis, or it issues a warning in
- -- a few cases where a suitable check flag is set for GNATprove to
- -- generate a check message.
-
- if GNATprove_Mode then
- Set_Raises_Constraint_Error (N);
- return;
+ if Emit_Message then
+ Discard_Node
+ (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
end if;
-- Now we replace the node by an N_Raise_Constraint_Error node
@@ -2986,7 +3089,6 @@ package body Sem_Util is
when N_Type_Conversion =>
if Do_Overflow_Check (Expr)
or else Do_Length_Check (Expr)
- or else Do_Tag_Check (Expr)
then
return False;
else
@@ -5607,6 +5709,13 @@ package body Sem_Util is
if Ekind (State_Id) = E_Constant then
null;
+ -- Overlays do not contribute to package state
+
+ elsif Ekind (State_Id) = E_Variable
+ and then Present (Ultimate_Overlaid_Entity (State_Id))
+ then
+ null;
+
-- Generate an error message of the form:
-- body of package ... has unused hidden states
@@ -6672,6 +6781,23 @@ package body Sem_Util is
return N;
end Compile_Time_Constraint_Error;
+ ----------------------------
+ -- Compute_Returns_By_Ref --
+ ----------------------------
+
+ procedure Compute_Returns_By_Ref (Func : Entity_Id) is
+ Typ : constant Entity_Id := Etype (Func);
+ Utyp : constant Entity_Id := Underlying_Type (Typ);
+
+ begin
+ if Is_Limited_View (Typ) then
+ Set_Returns_By_Ref (Func);
+
+ elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
+ Set_Returns_By_Ref (Func);
+ end if;
+ end Compute_Returns_By_Ref;
+
--------------------------------
-- Collect_Types_In_Hierarchy --
--------------------------------
@@ -7073,15 +7199,36 @@ package body Sem_Util is
end Current_Subprogram;
-------------------------------
+ -- CW_Or_Has_Controlled_Part --
+ -------------------------------
+
+ function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean is
+ begin
+ return Is_Class_Wide_Type (T) or else Needs_Finalization (T);
+ end CW_Or_Has_Controlled_Part;
+
+ -------------------------------
-- Deepest_Type_Access_Level --
-------------------------------
- function Deepest_Type_Access_Level (Typ : Entity_Id) return Uint is
+ function Deepest_Type_Access_Level
+ (Typ : Entity_Id;
+ Allow_Alt_Model : Boolean := True) return Uint
+ is
begin
if Ekind (Typ) = E_Anonymous_Access_Type
and then not Is_Local_Anonymous_Access (Typ)
and then Nkind (Associated_Node_For_Itype (Typ)) = N_Object_Declaration
then
+ -- No_Dynamic_Accessibility_Checks override for alternative
+ -- accessibility model.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (Typ)
+ then
+ return Type_Access_Level (Typ, Allow_Alt_Model);
+ end if;
+
-- Typ is the type of an Ada 2012 stand-alone object of an anonymous
-- access type.
@@ -7097,7 +7244,7 @@ package body Sem_Util is
return UI_From_Int (Int'Last);
else
- return Type_Access_Level (Typ);
+ return Type_Access_Level (Typ, Allow_Alt_Model);
end if;
end Deepest_Type_Access_Level;
@@ -7891,11 +8038,7 @@ package body Sem_Util is
Current_Node := Parent (Current_Node);
end loop;
- if Nkind (Current_Node) /= N_Compilation_Unit then
- return Empty;
- else
- return Current_Node;
- end if;
+ return Current_Node;
end Enclosing_Comp_Unit_Node;
--------------------------
@@ -10952,7 +11095,7 @@ package body Sem_Util is
Use_Full_View : Boolean := False) return Range_Nodes is
Result : Range_Nodes;
begin
- Get_Index_Bounds (N, Result.L, Result.H, Use_Full_View);
+ Get_Index_Bounds (N, Result.First, Result.Last, Use_Full_View);
return Result;
end Get_Index_Bounds;
@@ -10961,7 +11104,7 @@ package body Sem_Util is
Use_Full_View : Boolean := False) return Range_Values is
Nodes : constant Range_Nodes := Get_Index_Bounds (N, Use_Full_View);
begin
- return (Expr_Value (Nodes.L), Expr_Value (Nodes.H));
+ return (Expr_Value (Nodes.First), Expr_Value (Nodes.Last));
end Get_Index_Bounds;
-----------------------------
@@ -11691,7 +11834,7 @@ package body Sem_Util is
if Default = Known_Compatible
or else
(Etype (Obj) = Etype (Expr)
- and then (Unknown_Alignment (Obj)
+ and then (not Known_Alignment (Obj)
or else
Alignment (Obj) = Alignment (Etype (Obj))))
then
@@ -11794,22 +11937,23 @@ package body Sem_Util is
Set_Result (Known_Incompatible);
end if;
- -- See if Expr is an object with known alignment
+ -- See if Expr is an object with known alignment
elsif Is_Entity_Name (Expr)
and then Known_Alignment (Entity (Expr))
then
+ Offs := Uint_0;
ExpA := Alignment (Entity (Expr));
- -- Otherwise, we can use the alignment of the type of
- -- Expr given that we already checked for
- -- discombobulating rep clauses for the cases of indexed
- -- and selected components above.
+ -- Otherwise, we can use the alignment of the type of Expr
+ -- given that we already checked for discombobulating rep
+ -- clauses for the cases of indexed and selected components
+ -- above.
elsif Known_Alignment (Etype (Expr)) then
ExpA := Alignment (Etype (Expr));
- -- Otherwise the alignment is unknown
+ -- Otherwise the alignment is unknown
else
Set_Result (Default);
@@ -11821,28 +11965,28 @@ package body Sem_Util is
Set_Result (Known_Incompatible);
end if;
- -- If Expr is not a piece of a larger object, see if size
- -- is given. If so, check that it is not too small for the
- -- required alignment.
+ -- If Expr is a component or an entire object with a known
+ -- alignment, then we are fine. Otherwise, if its size is
+ -- known, it must be big enough for the required alignment.
if Offs /= No_Uint then
null;
- -- See if Expr is an object with known size
+ -- See if Expr is an object with known size
elsif Is_Entity_Name (Expr)
and then Known_Static_Esize (Entity (Expr))
then
SizA := Esize (Entity (Expr));
- -- Otherwise, we check the object size of the Expr type
+ -- Otherwise, we check the object size of the Expr type
elsif Known_Static_Esize (Etype (Expr)) then
SizA := Esize (Etype (Expr));
end if;
-- If we got a size, see if it is a multiple of the Obj
- -- alignment, if not, then the alignment cannot be
+ -- alignment; if not, then the alignment cannot be
-- acceptable, since the size is always a multiple of the
-- alignment.
@@ -11880,25 +12024,24 @@ package body Sem_Util is
-- where we do not know the alignment of Obj.
if Known_Alignment (Entity (Expr))
- and then UI_To_Int (Alignment (Entity (Expr))) <
- Ttypes.Maximum_Alignment
+ and then Alignment (Entity (Expr)) < Ttypes.Maximum_Alignment
then
Set_Result (Unknown);
- -- Now check size of Expr object. Any size that is not an
- -- even multiple of Maximum_Alignment is also worrisome
- -- since it may cause the alignment of the object to be less
- -- than the alignment of the type.
+ -- Now check size of Expr object. Any size that is not an even
+ -- multiple of Maximum_Alignment is also worrisome since it
+ -- may cause the alignment of the object to be less than the
+ -- alignment of the type.
elsif Known_Static_Esize (Entity (Expr))
and then
- (UI_To_Int (Esize (Entity (Expr))) mod
- (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit))
+ Esize (Entity (Expr)) mod
+ (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit)
/= 0
then
Set_Result (Unknown);
- -- Otherwise same type is decisive
+ -- Otherwise same type is decisive
else
Set_Result (Known_Compatible);
@@ -11936,7 +12079,7 @@ package body Sem_Util is
-- do it when there is an address clause since we can do more if the
-- alignment is known.
- if Unknown_Alignment (Obj) then
+ if not Known_Alignment (Obj) then
Set_Alignment (Obj, Alignment (Etype (Obj)));
end if;
@@ -13164,6 +13307,44 @@ package body Sem_Util is
and then Nkind (Node (First_Elmt (Constits))) = N_Null;
end Has_Null_Refinement;
+ ------------------------------------------
+ -- Has_Nonstatic_Class_Wide_Pre_Or_Post --
+ ------------------------------------------
+
+ function Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post
+ (Subp : Entity_Id) return Boolean
+ is
+ Disp_Type : constant Entity_Id := Find_Dispatching_Type (Subp);
+ Prag : Node_Id;
+ Pragma_Arg : Node_Id;
+
+ begin
+ if Present (Disp_Type)
+ and then Is_Abstract_Type (Disp_Type)
+ and then Present (Contract (Subp))
+ then
+ Prag := Pre_Post_Conditions (Contract (Subp));
+
+ while Present (Prag) loop
+ if Pragma_Name (Prag) in Name_Precondition | Name_Postcondition
+ and then Class_Present (Prag)
+ then
+ Pragma_Arg :=
+ Nlists.First
+ (Pragma_Argument_Associations (Prag));
+
+ if not Is_Static_Expression (Expression (Pragma_Arg)) then
+ return True;
+ end if;
+ end if;
+
+ Prag := Next_Pragma (Prag);
+ end loop;
+ end if;
+
+ return False;
+ end Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post;
+
-------------------------------
-- Has_Overriding_Initialize --
-------------------------------
@@ -14300,7 +14481,9 @@ package body Sem_Util is
-- In_Pre_Post_Condition --
---------------------------
- function In_Pre_Post_Condition (N : Node_Id) return Boolean is
+ function In_Pre_Post_Condition
+ (N : Node_Id; Class_Wide_Only : Boolean := False) return Boolean
+ is
Par : Node_Id;
Prag : Node_Id := Empty;
Prag_Id : Pragma_Id;
@@ -14326,13 +14509,24 @@ package body Sem_Util is
if Present (Prag) then
Prag_Id := Get_Pragma_Id (Prag);
- return
- Prag_Id = Pragma_Post
- or else Prag_Id = Pragma_Post_Class
- or else Prag_Id = Pragma_Postcondition
- or else Prag_Id = Pragma_Pre
- or else Prag_Id = Pragma_Pre_Class
- or else Prag_Id = Pragma_Precondition;
+ if Class_Wide_Only then
+ return
+ Prag_Id = Pragma_Post_Class
+ or else Prag_Id = Pragma_Pre_Class
+ or else (Class_Present (Prag)
+ and then (Prag_Id = Pragma_Post
+ or else Prag_Id = Pragma_Postcondition
+ or else Prag_Id = Pragma_Pre
+ or else Prag_Id = Pragma_Precondition));
+ else
+ return
+ Prag_Id = Pragma_Post
+ or else Prag_Id = Pragma_Post_Class
+ or else Prag_Id = Pragma_Postcondition
+ or else Prag_Id = Pragma_Pre
+ or else Prag_Id = Pragma_Pre_Class
+ or else Prag_Id = Pragma_Precondition;
+ end if;
-- Otherwise the node is not enclosed by a pre/postcondition pragma
@@ -15551,6 +15745,15 @@ package body Sem_Util is
-- statement is aliased if its type is immutably limited.
or else (Is_Return_Object (E)
+ and then Is_Limited_View (Etype (E)))
+
+ -- The current instance of a limited type is aliased, so
+ -- we want to allow uses of T'Access in the init proc for
+ -- a limited type T. However, we don't want to mark the formal
+ -- parameter as being aliased since that could impact callers.
+
+ or else (Is_Formal (E)
+ and then Chars (E) = Name_uInit
and then Is_Limited_View (Etype (E)));
elsif Nkind (Obj) = N_Selected_Component then
@@ -16069,11 +16272,9 @@ package body Sem_Util is
function Is_Concurrent_Interface (T : Entity_Id) return Boolean is
begin
- return Is_Interface (T)
- and then
- (Is_Protected_Interface (T)
- or else Is_Synchronized_Interface (T)
- or else Is_Task_Interface (T));
+ return Is_Protected_Interface (T)
+ or else Is_Synchronized_Interface (T)
+ or else Is_Task_Interface (T);
end Is_Concurrent_Interface;
-----------------------
@@ -17943,7 +18144,9 @@ package body Sem_Util is
Ent : constant Entity_Id := Entity (Expr);
Sub : constant Entity_Id := Enclosing_Subprogram (Ent);
begin
- if Ekind (Ent) not in E_Variable | E_In_Out_Parameter then
+ if Ekind (Ent)
+ not in E_Variable | E_In_Out_Parameter | E_Out_Parameter
+ then
return False;
else
return Present (Sub) and then Sub = Current_Subprogram;
@@ -18550,18 +18753,143 @@ package body Sem_Util is
return False;
end Is_Nontrivial_DIC_Procedure;
+ -----------------------
+ -- Is_Null_Extension --
+ -----------------------
+
+ function Is_Null_Extension
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
+ is
+ Type_Decl : Node_Id;
+ Type_Def : Node_Id;
+ begin
+ if Ignore_Privacy then
+ Type_Decl := Parent (Underlying_Type (Base_Type (T)));
+ else
+ Type_Decl := Parent (Base_Type (T));
+ if Nkind (Type_Decl) /= N_Full_Type_Declaration then
+ return False;
+ end if;
+ end if;
+ pragma Assert (Nkind (Type_Decl) = N_Full_Type_Declaration);
+ Type_Def := Type_Definition (Type_Decl);
+ if Present (Discriminant_Specifications (Type_Decl))
+ or else Nkind (Type_Def) /= N_Derived_Type_Definition
+ or else not Is_Tagged_Type (T)
+ or else No (Record_Extension_Part (Type_Def))
+ then
+ return False;
+ end if;
+
+ return Is_Null_Record_Definition (Record_Extension_Part (Type_Def));
+ end Is_Null_Extension;
+
+ --------------------------
+ -- Is_Null_Extension_Of --
+ --------------------------
+
+ function Is_Null_Extension_Of
+ (Descendant, Ancestor : Entity_Id) return Boolean
+ is
+ Ancestor_Type : constant Entity_Id
+ := Underlying_Type (Base_Type (Ancestor));
+ Descendant_Type : Entity_Id := Underlying_Type (Base_Type (Descendant));
+ begin
+ pragma Assert (Descendant_Type /= Ancestor_Type);
+ while Descendant_Type /= Ancestor_Type loop
+ if not Is_Null_Extension
+ (Descendant_Type, Ignore_Privacy => True)
+ then
+ return False;
+ end if;
+ Descendant_Type := Etype (Subtype_Indication
+ (Type_Definition (Parent (Descendant_Type))));
+ Descendant_Type := Underlying_Type (Base_Type (Descendant_Type));
+ end loop;
+ return True;
+ end Is_Null_Extension_Of;
+
+ -------------------------------
+ -- Is_Null_Record_Definition --
+ -------------------------------
+
+ function Is_Null_Record_Definition (Record_Def : Node_Id) return Boolean is
+ Item : Node_Id;
+ begin
+ -- Testing Null_Present is just an optimization, not required.
+
+ if Null_Present (Record_Def) then
+ return True;
+ elsif Present (Variant_Part (Component_List (Record_Def))) then
+ return False;
+ elsif not Present (Component_List (Record_Def)) then
+ return True;
+ end if;
+
+ Item := First (Component_Items (Component_List (Record_Def)));
+
+ while Present (Item) loop
+ if Nkind (Item) = N_Component_Declaration
+ and then Is_Internal_Name (Chars (Defining_Identifier (Item)))
+ then
+ null;
+ elsif Nkind (Item) = N_Pragma then
+ null;
+ else
+ return False;
+ end if;
+ Item := Next (Item);
+ end loop;
+
+ return True;
+ end Is_Null_Record_Definition;
+
-------------------------
-- Is_Null_Record_Type --
-------------------------
- function Is_Null_Record_Type (T : Entity_Id) return Boolean is
- Decl : constant Node_Id := Parent (T);
+ function Is_Null_Record_Type
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean
+ is
+ Decl : Node_Id;
+ Type_Def : Node_Id;
begin
- return Nkind (Decl) = N_Full_Type_Declaration
- and then Nkind (Type_Definition (Decl)) = N_Record_Definition
- and then
- (No (Component_List (Type_Definition (Decl)))
- or else Null_Present (Component_List (Type_Definition (Decl))));
+ if not Is_Record_Type (T) then
+ return False;
+ end if;
+
+ if Ignore_Privacy then
+ Decl := Parent (Underlying_Type (Base_Type (T)));
+ else
+ Decl := Parent (Base_Type (T));
+ if Nkind (Decl) /= N_Full_Type_Declaration then
+ return False;
+ end if;
+ end if;
+ pragma Assert (Nkind (Decl) = N_Full_Type_Declaration);
+ Type_Def := Type_Definition (Decl);
+
+ if Has_Discriminants (Defining_Identifier (Decl)) then
+ return False;
+ end if;
+
+ case Nkind (Type_Def) is
+ when N_Record_Definition =>
+ return Is_Null_Record_Definition (Type_Def);
+ when N_Derived_Type_Definition =>
+ if not Is_Null_Record_Type
+ (Etype (Subtype_Indication (Type_Def)),
+ Ignore_Privacy => Ignore_Privacy)
+ then
+ return False;
+ elsif not Is_Tagged_Type (T) then
+ return True;
+ else
+ return Is_Null_Extension (T, Ignore_Privacy => Ignore_Privacy);
+ end if;
+ when others =>
+ return False;
+ end case;
end Is_Null_Record_Type;
---------------------
@@ -18575,7 +18903,9 @@ package body Sem_Util is
-- This is because the parser always checks that prefixes of attributes
-- are named.
- return not (Is_Entity_Name (Prefix) and then Is_Type (Entity (Prefix)));
+ return not (Is_Entity_Name (Prefix)
+ and then Is_Type (Entity (Prefix))
+ and then not Is_Current_Instance (Prefix));
end Is_Object_Image;
-------------------------
@@ -19157,7 +19487,7 @@ package body Sem_Util is
elsif Is_Tagged_Type (Typ) then
return True;
- -- Case of non-discriminated record
+ -- Case of nondiscriminated record
else
declare
@@ -26675,6 +27005,8 @@ package body Sem_Util is
-- generated before the next instruction.
function Requires_Transient_Scope (Id : Entity_Id) return Boolean is
+ pragma Assert (if Present (Id) then Ekind (Id) in E_Void | Type_Kind);
+
function Caller_Known_Size_Record (Typ : Entity_Id) return Boolean;
-- This is called for untagged records and protected types, with
-- nondefaulted discriminants. Returns True if the size of function
@@ -26755,8 +27087,7 @@ package body Sem_Util is
-- Do not set Has_Controlled_Component on a class-wide equivalent
-- type. See Make_CW_Equivalent_Type.
- if Present (Typ)
- and then not Is_Frozen (Typ)
+ if not Is_Frozen (Typ)
and then Is_Base_Type (Typ)
and then (Is_Record_Type (Typ)
or else Is_Concurrent_Type (Typ)
@@ -26873,19 +27204,20 @@ package body Sem_Util is
-- Start of processing for Requires_Transient_Scope
begin
- Ensure_Minimum_Decoration (Id);
-
-- This is a private type which is not completed yet. This can only
-- happen in a default expression (of a formal parameter or of a
-- record component). Do not expand transient scope in this case.
if No (Typ) then
return False;
+ end if;
+
+ Ensure_Minimum_Decoration (Id);
-- Do not expand transient scope for non-existent procedure return or
-- string literal types.
- elsif Typ = Standard_Void_Type
+ if Typ = Standard_Void_Type
or else Ekind (Typ) = E_String_Literal_Subtype
then
return False;
@@ -28832,12 +29164,15 @@ package body Sem_Util is
-- Type_Access_Level --
-----------------------
- function Type_Access_Level (Typ : Entity_Id) return Uint is
- Btyp : Entity_Id;
+ function Type_Access_Level
+ (Typ : Entity_Id;
+ Allow_Alt_Model : Boolean := True;
+ Assoc_Ent : Entity_Id := Empty) return Uint
+ is
+ Btyp : Entity_Id := Base_Type (Typ);
+ Def_Ent : Entity_Id;
begin
- Btyp := Base_Type (Typ);
-
-- Ada 2005 (AI-230): For most cases of anonymous access types, we
-- simply use the level where the type is declared. This is true for
-- stand-alone object declarations, and for anonymous access types
@@ -28848,13 +29183,62 @@ package body Sem_Util is
if Is_Access_Type (Btyp) then
if Ekind (Btyp) = E_Anonymous_Access_Type then
+ -- No_Dynamic_Accessibility_Checks restriction override for
+ -- alternative accessibility model.
+
+ if Allow_Alt_Model
+ and then No_Dynamic_Accessibility_Checks_Enabled (Btyp)
+ then
+ -- In the -gnatd_b model, the level of an anonymous access
+ -- type is always that of the designated type.
+
+ if Debug_Flag_Underscore_B then
+ return Type_Access_Level
+ (Designated_Type (Btyp), Allow_Alt_Model);
+ end if;
+
+ -- When an anonymous access type's Assoc_Ent is specifiedi,
+ -- calculate the result based on the general accessibility
+ -- level routine.
+
+ -- We would like to use Associated_Node_For_Itype here instead,
+ -- but in some cases it is not fine grained enough ???
+
+ if Present (Assoc_Ent) then
+ return Static_Accessibility_Level
+ (Assoc_Ent, Object_Decl_Level);
+ end if;
+
+ -- Otherwise take the context of the anonymous access type into
+ -- account.
+
+ -- Obtain the defining entity for the internally generated
+ -- anonymous access type.
+
+ Def_Ent := Defining_Entity_Or_Empty
+ (Associated_Node_For_Itype (Typ));
+
+ if Present (Def_Ent) then
+ -- When the type comes from an anonymous access parameter,
+ -- the level is that of the subprogram declaration.
+
+ if Ekind (Def_Ent) in Subprogram_Kind then
+ return Scope_Depth (Def_Ent);
+
+ -- When the type is an access discriminant, the level is
+ -- that of the type.
+
+ elsif Ekind (Def_Ent) = E_Discriminant then
+ return Scope_Depth (Scope (Def_Ent));
+ end if;
+ end if;
-- If the type is a nonlocal anonymous access type (such as for
-- an access parameter) we treat it as being declared at the
-- library level to ensure that names such as X.all'access don't
-- fail static accessibility checks.
- if not Is_Local_Anonymous_Access (Typ) then
+ elsif not Is_Local_Anonymous_Access (Typ) then
return Scope_Depth (Standard_Standard);
-- If this is a return object, the accessibility level is that of
@@ -28888,7 +29272,7 @@ package body Sem_Util is
-- Treat the return object's type as having the level of the
-- function's result subtype (as per RM05-6.5(5.3/2)).
- return Type_Access_Level (Etype (Scop));
+ return Type_Access_Level (Etype (Scop), Allow_Alt_Model);
end;
end if;
end if;
@@ -28999,6 +29383,39 @@ package body Sem_Util is
end if;
end Type_Without_Stream_Operation;
+ ------------------------------
+ -- Ultimate_Overlaid_Entity --
+ ------------------------------
+
+ function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id is
+ Address : Node_Id;
+ Alias : Entity_Id := E;
+ Offset : Boolean;
+
+ begin
+ -- Currently this routine is only called for stand-alone objects that
+ -- have been analysed, since the analysis of the Address aspect is often
+ -- delayed.
+
+ pragma Assert (Ekind (E) in E_Constant | E_Variable);
+
+ loop
+ Address := Address_Clause (Alias);
+ if Present (Address) then
+ Find_Overlaid_Entity (Address, Alias, Offset);
+ if Present (Alias) then
+ null;
+ else
+ return Empty;
+ end if;
+ elsif Alias = E then
+ return Empty;
+ else
+ return Alias;
+ end if;
+ end loop;
+ end Ultimate_Overlaid_Entity;
+
---------------------
-- Ultimate_Prefix --
---------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 10375ff..b0d6a2a 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -65,15 +65,19 @@ package Sem_Util is
function Accessibility_Level
(Expr : Node_Id;
Level : Accessibility_Level_Kind;
- In_Return_Context : Boolean := False) return Node_Id;
+ In_Return_Context : Boolean := False;
+ Allow_Alt_Model : Boolean := True) return Node_Id;
-- Centralized accessibility level calculation routine for finding the
-- accessibility level of a given expression Expr.
- -- In_Return_Context forcing the Accessibility_Level calculations to be
+ -- In_Return_Context forces the Accessibility_Level calculations to be
-- carried out "as if" Expr existed in a return value. This is useful for
-- calculating the accessibility levels for discriminant associations
-- and return aggregates.
+ -- The Allow_Alt_Model parameter allows the alternative level calculation
+ -- under the restriction No_Dynamic_Accessibility_Checks to be performed.
+
function Acquire_Warning_Match_String (Str_Lit : Node_Id) return String;
-- Used by pragma Warnings (Off, string), and Warn_As_Error (string) to get
-- the given string argument, adding leading and trailing asterisks if they
@@ -157,13 +161,14 @@ package Sem_Util is
-- part of the current package.
procedure Apply_Compile_Time_Constraint_Error
- (N : Node_Id;
- Msg : String;
- Reason : RT_Exception_Code;
- Ent : Entity_Id := Empty;
- Typ : Entity_Id := Empty;
- Loc : Source_Ptr := No_Location;
- Warn : Boolean := False);
+ (N : Node_Id;
+ Msg : String;
+ Reason : RT_Exception_Code;
+ Ent : Entity_Id := Empty;
+ Typ : Entity_Id := Empty;
+ Loc : Source_Ptr := No_Location;
+ Warn : Boolean := False;
+ Emit_Message : Boolean := True);
-- N is a subexpression that will raise Constraint_Error when evaluated
-- at run time. Msg is a message that explains the reason for raising the
-- exception. The last character is ? if the message is always a warning,
@@ -185,6 +190,7 @@ package Sem_Util is
-- when the caller wants to parameterize whether an error or warning is
-- given), or when the message should be treated as a warning even when
-- SPARK_Mode is On (which otherwise would force an error).
+ -- If Emit_Message is False, then do not emit any message.
function Async_Readers_Enabled (Id : Entity_Id) return Boolean;
-- Id should be the entity of a state abstraction, an object, or a type.
@@ -582,6 +588,9 @@ package Sem_Util is
-- emitted immediately after the main message (and before output of any
-- message indicating that Constraint_Error will be raised).
+ procedure Compute_Returns_By_Ref (Func : Entity_Id);
+ -- Set the Returns_By_Ref flag on Func if appropriate
+
generic
with function Predicate (Typ : Entity_Id) return Boolean;
function Collect_Types_In_Hierarchy
@@ -653,7 +662,16 @@ package Sem_Util is
-- Current_Scope is returned. The returned value is Empty if this is called
-- from a library package which is not within any subprogram.
- function Deepest_Type_Access_Level (Typ : Entity_Id) return Uint;
+ function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean;
+ -- True if T is a class-wide type, or if it has controlled parts ("part"
+ -- means T or any of its subcomponents). Same as Needs_Finalization, except
+ -- when pragma Restrictions (No_Finalization) applies, in which case we
+ -- know that class-wide objects do not contain controlled parts.
+
+ function Deepest_Type_Access_Level
+ (Typ : Entity_Id;
+ Allow_Alt_Model : Boolean := True) return Uint;
+
-- Same as Type_Access_Level, except that if the type is the type of an Ada
-- 2012 stand-alone object of an anonymous access type, then return the
-- static accessibility level of the object. In that case, the dynamic
@@ -663,6 +681,9 @@ package Sem_Util is
-- in the case of a descendant of a generic formal type (returns Int'Last
-- instead of 0).
+ -- The Allow_Alt_Model parameter allows the alternative level calculation
+ -- under the restriction No_Dynamic_Accessibility_Checks to be performed.
+
function Defining_Entity (N : Node_Id) return Entity_Id;
-- Given a declaration N, returns the associated defining entity. If the
-- declaration has a specification, the entity is obtained from the
@@ -1168,11 +1189,11 @@ package Sem_Util is
-- arise during normal compilation of semantically correct programs.
type Range_Nodes is record
- L, H : Node_Id; -- First and Last nodes of a discrete_range
+ First, Last : Node_Id; -- First and Last nodes of a discrete_range
end record;
type Range_Values is record
- L, H : Uint; -- First and Last values of a discrete_range
+ First, Last : Uint; -- First and Last values of a discrete_range
end record;
function Get_Index_Bounds
@@ -1497,6 +1518,12 @@ package Sem_Util is
-- integer for use in compile-time checking. Note: Level is restricted to
-- be non-dynamic.
+ function Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post
+ (Subp : Entity_Id) return Boolean;
+ -- Return True if Subp is a primitive of an abstract type, where the
+ -- primitive has a class-wide pre- or postcondition whose expression
+ -- is nonstatic.
+
function Has_Overriding_Initialize (T : Entity_Id) return Boolean;
-- Predicate to determine whether a controlled type has a user-defined
-- Initialize primitive (and, in Ada 2012, whether that primitive is
@@ -1615,9 +1642,11 @@ package Sem_Util is
function In_Pragma_Expression (N : Node_Id; Nam : Name_Id) return Boolean;
-- Returns true if the expression N occurs within a pragma with name Nam
- function In_Pre_Post_Condition (N : Node_Id) return Boolean;
+ function In_Pre_Post_Condition
+ (N : Node_Id; Class_Wide_Only : Boolean := False) return Boolean;
-- Returns True if node N appears within a pre/postcondition pragma. Note
- -- the pragma Check equivalents are NOT considered.
+ -- the pragma Check equivalents are NOT considered. If Class_Wide_Only is
+ -- True, then tests for N appearing within a class-wide pre/postcondition.
function In_Quantified_Expression (N : Node_Id) return Boolean;
-- Returns true if the expression N occurs within a quantified expression
@@ -2094,9 +2123,8 @@ package Sem_Util is
-- limited view must be treated in the same way.
function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean;
- -- Determines whether Expr is a reference to a variable or IN OUT mode
- -- parameter of the current enclosing subprogram.
- -- Why are OUT parameters not considered here ???
+ -- Determines whether Expr is a reference to a variable or formal parameter
+ -- of mode OUT or IN OUT of the current enclosing subprogram.
function Is_Master (N : Node_Id) return Boolean;
-- Determine if the given node N constitutes a finalization master
@@ -2117,9 +2145,28 @@ package Sem_Util is
-- assertion expression of pragma Default_Initial_Condition and if it does,
-- the encapsulated expression is nontrivial.
- function Is_Null_Record_Type (T : Entity_Id) return Boolean;
- -- Determine whether T is declared with a null record definition or a
- -- null component list.
+ function Is_Null_Extension
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean;
+ -- Given a tagged type, returns True if argument is a type extension
+ -- that introduces no new components (discriminant or nondiscriminant).
+ -- Ignore_Privacy should be True for use in implementing dynamic semantics.
+
+ function Is_Null_Extension_Of
+ (Descendant, Ancestor : Entity_Id) return Boolean;
+ -- Given two tagged types, the first a descendant of the second,
+ -- returns True if every component of Descendant is inherited
+ -- (directly or indirectly) from Ancestor. Privacy is ignored.
+
+ function Is_Null_Record_Definition (Record_Def : Node_Id) return Boolean;
+ -- Returns True for an N_Record_Definition node that has no user-defined
+ -- components (and no variant part).
+
+ function Is_Null_Record_Type
+ (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean;
+ -- Determine whether T is declared with a null record definition, a
+ -- null component list, or as a type derived from a null record type
+ -- (with a null extension if tagged). Returns True for interface types,
+ -- False for discriminated types.
function Is_Object_Image (Prefix : Node_Id) return Boolean;
-- Returns True if an 'Img, 'Image, 'Wide_Image, or 'Wide_Wide_Image
@@ -2556,8 +2603,7 @@ package Sem_Util is
-- entity E. If no such instance exits, return Empty.
function Needs_Finalization (Typ : Entity_Id) return Boolean;
- -- Determine whether type Typ is controlled and thus requires finalization
- -- actions.
+ -- True if Typ requires finalization actions
function Needs_One_Actual (E : Entity_Id) return Boolean;
-- Returns True if a function has defaults for all but its first formal,
@@ -2865,9 +2911,9 @@ package Sem_Util is
procedure Propagate_Concurrent_Flags
(Typ : Entity_Id;
Comp_Typ : Entity_Id);
- -- Set Has_Task, Has_Protected and Has_Timing_Event on Typ when the flags
- -- are set on Comp_Typ. This follows the definition of these flags which
- -- are set (recursively) on any composite type which has a component marked
+ -- Set Has_Task, Has_Protected, and Has_Timing_Event on Typ when the flags
+ -- are set on Comp_Typ. This follows the definition of these flags, which
+ -- are set (recursively) on any composite type that has a component marked
-- by one of these flags. This procedure can only set flags for Typ, and
-- never clear them. Comp_Typ is the type of a component or a parent.
@@ -2880,14 +2926,14 @@ package Sem_Util is
procedure Propagate_Invariant_Attributes
(Typ : Entity_Id;
From_Typ : Entity_Id);
- -- Inherit all invariant-related attributes form type From_Typ. Typ is the
+ -- Inherit all invariant-related attributes from type From_Typ. Typ is the
-- destination type.
procedure Propagate_Predicate_Attributes
(Typ : Entity_Id;
From_Typ : Entity_Id);
- -- Inherit some predicate-related attributes form type From_Typ. Typ is the
- -- destination type. Probably to be completed with more attributes???
+ -- Inherit predicate functions and Has_Predicates flag from type From_Typ.
+ -- Typ is the destination type.
procedure Record_Possible_Part_Of_Reference
(Var_Id : Entity_Id;
@@ -3219,9 +3265,19 @@ package Sem_Util is
-- returned, i.e. Traverse_More_Func is called and the result is simply
-- discarded.
- function Type_Access_Level (Typ : Entity_Id) return Uint;
+ function Type_Access_Level
+ (Typ : Entity_Id;
+ Allow_Alt_Model : Boolean := True;
+ Assoc_Ent : Entity_Id := Empty) return Uint;
-- Return the accessibility level of Typ
+ -- The Allow_Alt_Model parameter allows the alternative level calculation
+ -- under the restriction No_Dynamic_Accessibility_Checks to be performed.
+
+ -- Assoc_Ent allows for the optional specification of the entity associated
+ -- with Typ. This gets utilized mostly for anonymous access type
+ -- processing, where context matters in interpreting Typ's level.
+
function Type_Without_Stream_Operation
(T : Entity_Id;
Op : TSS_Name_Type := TSS_Null) return Entity_Id;
@@ -3233,6 +3289,15 @@ package Sem_Util is
-- prevents the construction of a composite stream operation. If Op is
-- specified we check only for the given stream operation.
+ function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id;
+ -- If entity E is overlaying some other entity via an Address clause (which
+ -- possibly overlays yet another entity via its own Address clause), then
+ -- return the ultimate overlaid entity. If entity E is not overlaying any
+ -- other entity (or the overlaid entity cannot be determined statically),
+ -- then return Empty.
+ --
+ -- Subsidiary to the analysis of object overlays in SPARK.
+
function Ultimate_Prefix (N : Node_Id) return Node_Id;
-- Obtain the "outermost" prefix of arbitrary node N. Return N if no such
-- prefix exists.
diff --git a/gcc/ada/sigtramp-vxworks-target.inc b/gcc/ada/sigtramp-vxworks-target.h
index 5a37b87..8c43451 100644
--- a/gcc/ada/sigtramp-vxworks-target.inc
+++ b/gcc/ada/sigtramp-vxworks-target.h
@@ -6,7 +6,7 @@
* *
* Asm Implementation Include File *
* *
- * Copyright (C) 2011-2018, Free Software Foundation, Inc. *
+ * Copyright (C) 2011-2021, 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- *
diff --git a/gcc/ada/sigtramp-vxworks.c b/gcc/ada/sigtramp-vxworks.c
index b04d881..2455f6e 100644
--- a/gcc/ada/sigtramp-vxworks.c
+++ b/gcc/ada/sigtramp-vxworks.c
@@ -180,7 +180,7 @@ void __gnat_sigtramp (int signo, void *si, void *sc,
}
/* Include the target specific bits. */
-#include "sigtramp-vxworks-target.inc"
+#include "sigtramp-vxworks-target.h"
/* sigtramp stub for common registers. */
diff --git a/gcc/ada/sinfo-cn.adb b/gcc/ada/sinfo-cn.adb
index 9a9af9b..c676d47 100644
--- a/gcc/ada/sinfo-cn.adb
+++ b/gcc/ada/sinfo-cn.adb
@@ -56,7 +56,6 @@ package body Sinfo.CN is
procedure Change_Conversion_To_Unchecked (N : Node_Id) is
begin
Set_Do_Overflow_Check (N, False);
- Set_Do_Tag_Check (N, False);
Set_Do_Length_Check (N, False);
Mutate_Nkind (N, N_Unchecked_Type_Conversion);
end Change_Conversion_To_Unchecked;
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index fe4f4e1..71da7fc 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -689,11 +689,9 @@ package Sinfo is
-- The following flag fields appear in various nodes:
- -- Do_Accessibility_Check
-- Do_Discriminant_Check
-- Do_Length_Check
-- Do_Storage_Check
- -- Do_Tag_Check
-- These flags are used in some specific cases by the front end, either
-- during semantic analysis or during expansion, and cannot be expected
@@ -1012,7 +1010,7 @@ package Sinfo is
-- Present in N_Raise_Expression nodes that appear in the body of the
-- special predicateM function used to test a predicate in the context
-- of a membership test, where raise expression results in returning a
- -- value of False rather than raising an exception.???obsolete flag
+ -- value of False rather than raising an exception.
-- Corresponding_Aspect
-- Present in N_Pragma node. Used to point back to the source aspect from
@@ -1096,11 +1094,6 @@ package Sinfo is
-- discriminant checking functions are constructed. The purpose is to
-- avoid attempting to set these functions more than once.
- -- Do_Accessibility_Check
- -- This flag is set on N_Parameter_Specification nodes to indicate
- -- that an accessibility check is required for the parameter. It is
- -- not yet decided who takes care of this check???.
-
-- Do_Discriminant_Check
-- This flag is set on N_Selected_Component nodes to indicate that a
-- discriminant check is required using the discriminant check routine
@@ -1185,13 +1178,6 @@ package Sinfo is
-- to the runtime routine. The N_Subprogram_Body case is handled by the
-- backend, and all the semantics does is set the flag.
- -- Do_Tag_Check
- -- This flag is set on an N_Assignment_Statement, N_Function_Call,
- -- N_Procedure_Call_Statement, N_Type_Conversion,
- -- N_Simple_Return_Statement, or N_Extended_Return_Statement
- -- node to indicate that the tag check can be suppressed. It is not
- -- yet decided how this flag is used???.
-
-- Elaborate_Present
-- This flag is set in the N_With_Clause node to indicate that pragma
-- Elaborate pragma appears for the with'ed units.
@@ -2096,7 +2082,7 @@ package Sinfo is
-- that no elaboration check is needed on the call, because it appears in
-- the context of a local Suppress pragma. This is used on calls within
-- task bodies, where the actual elaboration checks are applied after
- -- analysis, when the local scope stack is not present
+ -- analysis, when the local scope stack is not present.
-- No_Entities_Ref_In_Spec
-- Present in N_With_Clause nodes. Set if the with clause is on the
@@ -4740,7 +4726,6 @@ package Sinfo is
-- Do_Discriminant_Check
-- Do_Length_Check
-- Float_Truncate
- -- Do_Tag_Check
-- Conversion_OK
-- Do_Overflow_Check
-- Rounded_Result
@@ -4913,7 +4898,6 @@ package Sinfo is
-- No_Ctrl_Actions
-- Has_Target_Names
-- Is_Elaboration_Code
- -- Do_Tag_Check
-- Componentwise_Assignment
-- Suppress_Assignment_Checks
@@ -5436,7 +5420,6 @@ package Sinfo is
-- Null_Exclusion_Present
-- Parameter_Type subtype mark or access definition
-- Expression (set to Empty if no default expression present)
- -- Do_Accessibility_Check
-- More_Ids (set to False if no more identifiers in list)
-- Prev_Ids (set to False if no previous identifiers in list)
-- Default_Expression
@@ -5505,7 +5488,6 @@ package Sinfo is
-- Is_SPARK_Mode_On_Node
-- Is_Elaboration_Warnings_OK_Node
-- No_Elaboration_Check
- -- Do_Tag_Check
-- Is_Known_Guaranteed_ABE
-- plus fields for expression
@@ -5539,7 +5521,6 @@ package Sinfo is
-- Is_Elaboration_Warnings_OK_Node
-- No_Elaboration_Check
-- Is_Expanded_Build_In_Place_Call
- -- Do_Tag_Check
-- No_Side_Effect_Removal
-- Is_Known_Guaranteed_ABE
-- plus fields for expression
@@ -5602,7 +5583,6 @@ package Sinfo is
-- Expression (set to Empty if no expression present)
-- Storage_Pool
-- Procedure_To_Call
- -- Do_Tag_Check
-- By_Ref
-- Comes_From_Extended_Return_Statement
@@ -5618,7 +5598,6 @@ package Sinfo is
-- Handled_Statement_Sequence (set to Empty if not present)
-- Storage_Pool
-- Procedure_To_Call
- -- Do_Tag_Check
-- By_Ref
-- Note: Return_Statement_Entity points to an E_Return_Statement.
@@ -8441,8 +8420,11 @@ package Sinfo is
-- An unchecked type conversion node represents the semantic action
-- corresponding to a call to an instantiation of Unchecked_Conversion.
-- It is generated as a result of actual use of Unchecked_Conversion
- -- and also the expander generates unchecked type conversion nodes
- -- directly for expansion of complex semantic actions.
+ -- and also by the expander.
+
+ -- Unchecked type conversion nodes should be created by calling
+ -- Tbuild.Unchecked_Convert_To, rather than by directly calling
+ -- Nmake.Make_Unchecked_Type_Conversion.
-- Note: an unchecked type conversion is a variable as far as the
-- semantics are concerned, which is convenient for the expander.
diff --git a/gcc/ada/sinput-l.adb b/gcc/ada/sinput-l.adb
index 102f363..2d5efb0 100644
--- a/gcc/ada/sinput-l.adb
+++ b/gcc/ada/sinput-l.adb
@@ -551,19 +551,10 @@ package body Sinput.L is
Set_Source_File_Index_Table (X);
if Opt.List_Preprocessing_Symbols then
- Get_Name_String (N);
-
declare
- Foreword : String (1 .. Foreword_Start'Length +
- Name_Len + Foreword_End'Length);
-
+ Foreword : constant String :=
+ Foreword_Start & Get_Name_String (N) & Foreword_End;
begin
- Foreword (1 .. Foreword_Start'Length) := Foreword_Start;
- Foreword (Foreword_Start'Length + 1 ..
- Foreword_Start'Length + Name_Len) :=
- Name_Buffer (1 .. Name_Len);
- Foreword (Foreword'Last - Foreword_End'Length + 1 ..
- Foreword'Last) := Foreword_End;
Prep.List_Symbols (Foreword);
end;
end if;
@@ -654,14 +645,13 @@ package body Sinput.L is
NB : Integer;
Status : Boolean;
- begin
- Get_Name_String (N);
- Add_Str_To_Name_Buffer (Prep_Suffix);
+ Prep_Filename : constant String :=
+ Get_Name_String (N) & Prep_Suffix;
- Delete_File (Name_Buffer (1 .. Name_Len), Status);
+ begin
+ Delete_File (Prep_Filename, Status);
- FD :=
- Create_New_File (Name_Buffer (1 .. Name_Len), Text);
+ FD := Create_New_File (Prep_Filename, Text);
Status := FD /= Invalid_FD;
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index b9ca607..a67623b 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -439,6 +439,7 @@ package Snames is
-- correctly recognize and process Fast_Math.
Name_Favor_Top_Level : constant Name_Id := N + $; -- GNAT
+ Name_GNAT_Annotate : constant Name_Id := N + $; -- GNAT
Name_Ignore_Pragma : constant Name_Id := N + $; -- GNAT
Name_Implicit_Packing : constant Name_Id := N + $; -- GNAT
Name_Initialize_Scalars : constant Name_Id := N + $; -- GNAT
@@ -796,7 +797,6 @@ package Snames is
Name_Gcc : constant Name_Id := N + $;
Name_General : constant Name_Id := N + $;
Name_Gnat : constant Name_Id := N + $;
- Name_Gnat_Annotate : constant Name_Id := N + $;
Name_Gnat_Extended_Ravenscar : constant Name_Id := N + $;
Name_Gnat_Ravenscar_EDF : constant Name_Id := N + $;
Name_Gnatprove : constant Name_Id := N + $;
@@ -827,6 +827,7 @@ package Snames is
Name_No_Access_Parameter_Allocators : constant Name_Id := N + $;
Name_No_Coextensions : constant Name_Id := N + $;
Name_No_Dependence : constant Name_Id := N + $;
+ Name_No_Dynamic_Accessibility_Checks : constant Name_Id := N + $;
Name_No_Dynamic_Attachment : constant Name_Id := N + $;
Name_No_Dynamic_Interrupts : constant Name_Id := N + $;
Name_No_Elaboration_Code : constant Name_Id := N + $;
@@ -1767,6 +1768,7 @@ package Snames is
Pragma_Extensions_Allowed,
Pragma_External_Name_Casing,
Pragma_Favor_Top_Level,
+ Pragma_GNAT_Annotate,
Pragma_Ignore_Pragma,
Pragma_Implicit_Packing,
Pragma_Initialize_Scalars,
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index 4467929..c1f1ede 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -1065,16 +1065,12 @@ package body Sprint is
if Present (Expressions (Node)) then
Sprint_Comma_List (Expressions (Node));
- if Present (Component_Associations (Node))
- and then not Is_Empty_List (Component_Associations (Node))
- then
+ if not Is_Empty_List (Component_Associations (Node)) then
Write_Str (", ");
end if;
end if;
- if Present (Component_Associations (Node))
- and then not Is_Empty_List (Component_Associations (Node))
- then
+ if not Is_Empty_List (Component_Associations (Node)) then
Indent_Begin;
declare
diff --git a/gcc/ada/style.adb b/gcc/ada/style.adb
index 1409cc6..c2bff83 100644
--- a/gcc/ada/style.adb
+++ b/gcc/ada/style.adb
@@ -265,11 +265,15 @@ package body Style is
-- indicators were introduced in Ada 2005. We apply Comes_From_Source
-- to Original_Node to catch the case of a procedure body declared with
-- "is null" that has been rewritten as a normal empty body.
+ -- We do not emit a warning on an inherited operation that comes from
+ -- a type derivation.
if Style_Check_Missing_Overriding
and then (Comes_From_Source (Original_Node (N))
or else Is_Generic_Instance (E))
and then Ada_Version_Explicit >= Ada_2005
+ and then Present (Parent (E))
+ and then Nkind (Parent (E)) /= N_Full_Type_Declaration
then
-- If the subprogram is an instantiation, its declaration appears
-- within a wrapper package that precedes the instance node. Place
diff --git a/gcc/ada/targparm.ads b/gcc/ada/targparm.ads
index 28465ea..302247f 100644
--- a/gcc/ada/targparm.ads
+++ b/gcc/ada/targparm.ads
@@ -365,12 +365,12 @@ package Targparm is
-- this flag is False, and the use of aggregates is not permitted.
Support_Atomic_Primitives_On_Target : Boolean := False;
- -- If this flag is True, then the back-end support GCC built-in atomic
- -- operations for memory model such as atomic load or atomic compare
+ -- If this flag is True, then the back end supports GCC built-in atomic
+ -- operations for memory model, such as atomic load or atomic compare
-- exchange (see the GCC manual for more information). If the flag is
- -- False, then the back-end doesn't provide this support. Note this flag is
- -- set to True only if the target supports all atomic primitives up to 64
- -- bits. ??? To be modified.
+ -- False, then the back end doesn't provide this support. Note that this
+ -- flag is set to True only if the target supports all atomic primitives
+ -- up to 64 bits.
Support_Composite_Assign_On_Target : Boolean := True;
-- The assignment of composite objects other than small records and
diff --git a/gcc/ada/tbuild.adb b/gcc/ada/tbuild.adb
index 4c53cdb..4d9c1c4 100644
--- a/gcc/ada/tbuild.adb
+++ b/gcc/ada/tbuild.adb
@@ -29,14 +29,12 @@ with Csets; use Csets;
with Einfo; use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils; use Einfo.Utils;
-with Elists; use Elists;
with Lib; use Lib;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Opt; use Opt;
with Restrict; use Restrict;
with Rident; use Rident;
-with Sem_Aux; use Sem_Aux;
with Sinfo.Utils; use Sinfo.Utils;
with Sem_Util; use Sem_Util;
with Snames; use Snames;
@@ -117,6 +115,7 @@ package body Tbuild is
----------------
function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
+ pragma Assert (Is_Type (Typ));
Result : Node_Id;
begin
@@ -185,32 +184,6 @@ package body Tbuild is
return N;
end Make_Byte_Aligned_Attribute_Reference;
- --------------------
- -- Make_DT_Access --
- --------------------
-
- function Make_DT_Access
- (Loc : Source_Ptr;
- Rec : Node_Id;
- Typ : Entity_Id) return Node_Id
- is
- Full_Type : Entity_Id := Typ;
-
- begin
- if Is_Private_Type (Typ) then
- Full_Type := Underlying_Type (Typ);
- end if;
-
- return
- Unchecked_Convert_To (
- New_Occurrence_Of
- (Etype (Node (First_Elmt (Access_Disp_Table (Full_Type)))), Loc),
- Make_Selected_Component (Loc,
- Prefix => New_Copy (Rec),
- Selector_Name =>
- New_Occurrence_Of (First_Tag_Component (Full_Type), Loc)));
- end Make_DT_Access;
-
------------------------
-- Make_Float_Literal --
------------------------
@@ -906,26 +879,34 @@ package body Tbuild is
(Typ : Entity_Id;
Expr : Node_Id) return Node_Id
is
+ pragma Assert (Ekind (Typ) in E_Void | Type_Kind);
+ -- We don't really want to allow E_Void here, but existing code passes
+ -- it.
+
Loc : constant Source_Ptr := Sloc (Expr);
Result : Node_Id;
- Expr_Parent : Node_Id;
begin
-- If the expression is already of the correct type, then nothing
- -- to do, except for relocating the node in case this is required.
+ -- to do, except for relocating the node
if Present (Etype (Expr))
- and then (Base_Type (Etype (Expr)) = Typ
- or else Etype (Expr) = Typ)
+ and then (Base_Type (Etype (Expr)) = Typ or else Etype (Expr) = Typ)
then
return Relocate_Node (Expr);
- -- Case where the expression is itself an unchecked conversion to
- -- the same type, and we can thus eliminate the outer conversion.
+ -- Case where the expression is already an unchecked conversion. We
+ -- replace the type being converted to, to avoid creating an unchecked
+ -- conversion of an unchecked conversion. Extra unchecked conversions
+ -- make the .dg output less readable. We can't do this in cases
+ -- involving bitfields, because the sizes might not match. The
+ -- Is_Composite_Type checks avoid such cases.
elsif Nkind (Expr) = N_Unchecked_Type_Conversion
- and then Entity (Subtype_Mark (Expr)) = Typ
+ and then Is_Composite_Type (Etype (Expr))
+ and then Is_Composite_Type (Typ)
then
+ Set_Subtype_Mark (Expr, New_Occurrence_Of (Typ, Loc));
Result := Relocate_Node (Expr);
elsif Nkind (Expr) = N_Null
@@ -938,18 +919,15 @@ package body Tbuild is
-- All other cases
else
- -- Capture the parent of the expression before relocating it and
- -- creating the conversion, so the conversion's parent can be set
- -- to the original parent below.
-
- Expr_Parent := Parent (Expr);
-
- Result :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Typ, Loc),
- Expression => Relocate_Node (Expr));
-
- Set_Parent (Result, Expr_Parent);
+ declare
+ Expr_Parent : constant Node_Id := Parent (Expr);
+ begin
+ Result :=
+ Make_Unchecked_Type_Conversion (Loc,
+ Subtype_Mark => New_Occurrence_Of (Typ, Loc),
+ Expression => Relocate_Node (Expr));
+ Set_Parent (Result, Expr_Parent);
+ end;
end if;
Set_Etype (Result, Typ);
diff --git a/gcc/ada/tbuild.ads b/gcc/ada/tbuild.ads
index 07cd7a7..eb17865 100644
--- a/gcc/ada/tbuild.ads
+++ b/gcc/ada/tbuild.ads
@@ -41,19 +41,16 @@ package Tbuild is
-- except that it will be analyzed and resolved with checks off.
function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id;
- -- Returns an expression that represents the result of a checked convert
- -- of expression Exp to type T. If the base type of Exp is T, then no
- -- conversion is required, and Exp is returned unchanged. Otherwise an
- -- N_Type_Conversion node is constructed to convert the expression.
- -- If an N_Type_Conversion node is required, Relocate_Node is used on
- -- Exp. This means that it is safe to replace a node by a Convert_To
- -- of itself to some other type.
+ -- Returns an expression that is a type conversion of expression Expr to
+ -- type Typ. If the type of Expr is Typ, then no conversion is required.
+ -- Otherwise an N_Type_Conversion node is constructed to convert the
+ -- expression. Relocate_Node is applied to Expr, so that it is safe to
+ -- replace a node by a Convert_To of itself to some other type.
procedure Convert_To_And_Rewrite (Typ : Entity_Id; Expr : Node_Id);
pragma Inline (Convert_To_And_Rewrite);
-- Like the function, except that there is an extra step of calling
-- Rewrite on the Expr node and replacing it with the converted result.
- -- As noted above, this is safe, because Relocate_Node is called.
procedure Discard_Node (N : Node_Or_Entity_Id);
pragma Inline (Discard_Node);
@@ -78,11 +75,6 @@ package Tbuild is
-- Must_Be_Byte_Aligned is set in the attribute reference node. The
-- Attribute_Name must be Name_Address or Name_Unrestricted_Access.
- function Make_DT_Access
- (Loc : Source_Ptr; Rec : Node_Id; Typ : Entity_Id) return Node_Id;
- -- Create an access to the Dispatch Table by using the Tag field of a
- -- tagged record : Acc_Dt (Rec.tag).all
-
function Make_Float_Literal
(Loc : Source_Ptr;
Radix : Uint;
@@ -319,13 +311,12 @@ package Tbuild is
function New_Occurrence_Of
(Def_Id : Entity_Id;
Loc : Source_Ptr) return Node_Id;
- -- New_Occurrence_Of creates an N_Identifier node which is an occurrence
- -- of the defining identifier which is passed as its argument. The Entity
- -- and Etype of the result are set from the given defining identifier as
- -- follows: Entity is simply a copy of Def_Id. Etype is a copy of Def_Id
- -- for types, and a copy of the Etype of Def_Id for other entities. Note
- -- that Is_Static_Expression is set if this call creates an occurrence of
- -- an enumeration literal.
+ -- New_Occurrence_Of creates an N_Identifier node that is an occurrence of
+ -- the defining identifier Def_Id. The Entity and Etype of the result are
+ -- set from the given defining identifier as follows: Entity is a copy of
+ -- Def_Id. Etype is a copy of Def_Id for types, and a copy of the Etype of
+ -- Def_Id for other entities. Note that Is_Static_Expression is set if this
+ -- call creates an occurrence of an enumeration literal.
function New_Suffixed_Name
(Related_Id : Name_Id;
@@ -349,7 +340,10 @@ package Tbuild is
(Typ : Entity_Id;
Expr : Node_Id) return Node_Id;
-- Like Convert_To, but if a conversion is actually needed, constructs an
- -- N_Unchecked_Type_Conversion node to do the required conversion.
+ -- N_Unchecked_Type_Conversion node to do the required conversion. Unlike
+ -- Convert_To, a new node is not required if Expr is already of the correct
+ -- BASE type, and if a new node is created, the Parent of Expr is copied to
+ -- it.
-------------------------------------
-- Subprograms for Use by Gnat1drv --
diff --git a/gcc/ada/ttypes.ads b/gcc/ada/ttypes.ads
index ee0c1d3..5f59607 100644
--- a/gcc/ada/ttypes.ads
+++ b/gcc/ada/ttypes.ads
@@ -210,7 +210,7 @@ package Ttypes is
Set_Targ.Strict_Alignment /= 0;
-- True if instructions will fail if data is misaligned. Note that this
-- is a variable rather than a constant since it can be modified (set to
- -- True) if the debug flag -gnatd.A is used.
+ -- True) if the debug flag -gnatd.a is used.
Target_Double_Float_Alignment : constant Nat :=
Set_Targ.Double_Float_Alignment;
diff --git a/gcc/ada/uname.adb b/gcc/ada/uname.adb
index ca937ef..18cb6d1 100644
--- a/gcc/ada/uname.adb
+++ b/gcc/ada/uname.adb
@@ -47,15 +47,18 @@ package body Uname is
-------------------
function Get_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
+ Append (Buffer, N);
+
+ pragma Assert
+ (Buffer.Length > 2
+ and then Buffer.Chars (Buffer.Length - 1) = '%'
+ and then Buffer.Chars (Buffer.Length) = 's');
- pragma Assert (Name_Len > 2
- and then Name_Buffer (Name_Len - 1) = '%'
- and then Name_Buffer (Name_Len) = 's');
+ Buffer.Chars (Buffer.Length) := 'b';
- Name_Buffer (Name_Len) := 'b';
- return Name_Find;
+ return Name_Find (Buffer);
end Get_Body_Name;
-----------------------------------
@@ -111,19 +114,19 @@ package body Uname is
--------------------------
function Get_Parent_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
+ Append (Buffer, N);
- while Name_Buffer (Name_Len) /= '.' loop
- pragma Assert (Name_Len > 1); -- not a child or subunit name
- Name_Len := Name_Len - 1;
+ while Buffer.Chars (Buffer.Length) /= '.' loop
+ pragma Assert (Buffer.Length > 1); -- not a child or subunit name
+ Buffer.Length := Buffer.Length - 1;
end loop;
- Name_Buffer (Name_Len) := '%';
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := 'b';
- return Name_Find;
+ Buffer.Chars (Buffer.Length) := '%';
+ Append (Buffer, 'b');
+ return Name_Find (Buffer);
end Get_Parent_Body_Name;
--------------------------
@@ -131,22 +134,22 @@ package body Uname is
--------------------------
function Get_Parent_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
+ Append (Buffer, N);
- while Name_Buffer (Name_Len) /= '.' loop
- if Name_Len = 1 then
+ while Buffer.Chars (Buffer.Length) /= '.' loop
+ if Buffer.Length = 1 then
return No_Unit_Name;
else
- Name_Len := Name_Len - 1;
+ Buffer.Length := Buffer.Length - 1;
end if;
end loop;
- Name_Buffer (Name_Len) := '%';
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := 's';
- return Name_Find;
+ Buffer.Chars (Buffer.Length) := '%';
+ Append (Buffer, 's');
+ return Name_Find (Buffer);
end Get_Parent_Spec_Name;
-------------------
@@ -154,15 +157,18 @@ package body Uname is
-------------------
function Get_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
+ Append (Buffer, N);
+
+ pragma Assert
+ (Buffer.Length > 2
+ and then Buffer.Chars (Buffer.Length - 1) = '%'
+ and then Buffer.Chars (Buffer.Length) = 'b');
- pragma Assert (Name_Len > 2
- and then Name_Buffer (Name_Len - 1) = '%'
- and then Name_Buffer (Name_Len) = 'b');
+ Buffer.Chars (Buffer.Length) := 's';
- Name_Buffer (Name_Len) := 's';
- return Name_Find;
+ return Name_Find (Buffer);
end Get_Spec_Name;
-------------------
@@ -171,13 +177,8 @@ package body Uname is
function Get_Unit_Name (N : Node_Id) return Unit_Name_Type is
- Unit_Name_Buffer : String (1 .. Hostparm.Max_Name_Length);
- -- Buffer used to build name of unit. Note that we cannot use the
- -- Name_Buffer in package Name_Table because we use it to read
- -- component names.
-
- Unit_Name_Length : Natural := 0;
- -- Length of name stored in Unit_Name_Buffer
+ Unit_Name_Buffer : Bounded_String;
+ -- Buffer used to build name of unit
Node : Node_Id;
-- Program unit node
@@ -200,9 +201,7 @@ package body Uname is
procedure Add_Char (C : Character) is
begin
- -- Should really check for max length exceeded here???
- Unit_Name_Length := Unit_Name_Length + 1;
- Unit_Name_Buffer (Unit_Name_Length) := C;
+ Append (Unit_Name_Buffer, C);
end Add_Char;
--------------
@@ -211,11 +210,7 @@ package body Uname is
procedure Add_Name (Name : Name_Id) is
begin
- Get_Name_String (Name);
-
- for J in 1 .. Name_Len loop
- Add_Char (Name_Buffer (J));
- end loop;
+ Append (Unit_Name_Buffer, Name);
end Add_Name;
-------------------
@@ -223,8 +218,6 @@ package body Uname is
-------------------
procedure Add_Node_Name (Node : Node_Id) is
- Kind : constant Node_Kind := Nkind (Node);
-
begin
-- Just ignore an error node (someone else will give a message)
@@ -234,7 +227,7 @@ package body Uname is
-- Otherwise see what kind of node we have
else
- case Kind is
+ case Nkind (Node) is
when N_Defining_Identifier
| N_Defining_Operator_Symbol
| N_Identifier
@@ -367,8 +360,8 @@ package body Uname is
Node := Declaration_Node (Entity (Node));
end if;
- if Nkind (Node) = N_Package_Specification
- or else Nkind (Node) in N_Subprogram_Specification
+ if Nkind (Node) in N_Package_Specification
+ | N_Subprogram_Specification
then
Node := Parent (Node);
end if;
@@ -410,11 +403,7 @@ package body Uname is
raise Program_Error;
end case;
- Name_Buffer (1 .. Unit_Name_Length) :=
- Unit_Name_Buffer (1 .. Unit_Name_Length);
- Name_Len := Unit_Name_Length;
- return Name_Find;
-
+ return Name_Find (Unit_Name_Buffer);
end Get_Unit_Name;
--------------------------
@@ -491,11 +480,12 @@ package body Uname is
------------------
function Is_Body_Name (N : Unit_Name_Type) return Boolean is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
- return Name_Len > 2
- and then Name_Buffer (Name_Len - 1) = '%'
- and then Name_Buffer (Name_Len) = 'b';
+ Append (Buffer, N);
+ return Buffer.Length > 2
+ and then Buffer.Chars (Buffer.Length - 1) = '%'
+ and then Buffer.Chars (Buffer.Length) = 'b';
end Is_Body_Name;
-------------------
@@ -503,17 +493,16 @@ package body Uname is
-------------------
function Is_Child_Name (N : Unit_Name_Type) return Boolean is
- J : Natural;
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
- J := Name_Len;
+ Append (Buffer, N);
- while Name_Buffer (J) /= '.' loop
- if J = 1 then
+ while Buffer.Chars (Buffer.Length) /= '.' loop
+ if Buffer.Length = 1 then
return False; -- not a child or subunit name
else
- J := J - 1;
+ Buffer.Length := Buffer.Length - 1;
end if;
end loop;
@@ -591,11 +580,12 @@ package body Uname is
------------------
function Is_Spec_Name (N : Unit_Name_Type) return Boolean is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
- return Name_Len > 2
- and then Name_Buffer (Name_Len - 1) = '%'
- and then Name_Buffer (Name_Len) = 's';
+ Append (Buffer, N);
+ return Buffer.Length > 2
+ and then Buffer.Chars (Buffer.Length - 1) = '%'
+ and then Buffer.Chars (Buffer.Length) = 's';
end Is_Spec_Name;
-----------------------
@@ -603,12 +593,11 @@ package body Uname is
-----------------------
function Name_To_Unit_Name (N : Name_Id) return Unit_Name_Type is
+ Buffer : Bounded_String;
begin
- Get_Name_String (N);
- Name_Buffer (Name_Len + 1) := '%';
- Name_Buffer (Name_Len + 2) := 's';
- Name_Len := Name_Len + 2;
- return Name_Find;
+ Append (Buffer, N);
+ Append (Buffer, "%s");
+ return Name_Find (Buffer);
end Name_To_Unit_Name;
---------------
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index cc0eb11..f0b2d96 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,301 @@
+2021-07-07 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-manager.cc (null_assignment_sm_context::get_state):
+ New overload.
+ (null_assignment_sm_context::set_next_state): New overload.
+ (null_assignment_sm_context::get_diagnostic_tree): New.
+ * engine.cc (impl_sm_context::get_state): New overload.
+ (impl_sm_context::set_next_state): New overload.
+ (impl_sm_context::get_diagnostic_tree): New overload.
+ (impl_region_model_context::on_condition): Convert params from
+ tree to const svalue *.
+ * exploded-graph.h (impl_region_model_context::on_condition):
+ Likewise.
+ * region-model.cc (region_model::on_call_pre): Move handling of
+ internal calls to before checking for get_fndecl_for_call.
+ (region_model::add_constraints_from_binop): New.
+ (region_model::add_constraint): Split out into a new overload
+ working on const svalue * rather than tree. Call
+ add_constraints_from_binop. Drop call to
+ add_any_constraints_from_ssa_def_stmt.
+ (region_model::add_any_constraints_from_ssa_def_stmt): Delete.
+ (region_model::add_any_constraints_from_gassign): Delete.
+ (region_model::add_any_constraints_from_gcall): Delete.
+ * region-model.h
+ (region_model::add_any_constraints_from_ssa_def_stmt): Delete.
+ (region_model::add_any_constraints_from_gassign): Delete.
+ (region_model::add_any_constraints_from_gcall): Delete.
+ (region_model::add_constraint): Add overload decl.
+ (region_model::add_constraints_from_binop): New decl.
+ (region_model_context::on_condition): Convert params from tree to
+ const svalue *.
+ (noop_region_model_context::on_condition): Likewise.
+ * sm-file.cc (fileptr_state_machine::condition): Likewise.
+ * sm-malloc.cc (malloc_state_machine::on_condition): Likewise.
+ * sm-pattern-test.cc: Include tristate.h, selftest.h,
+ analyzer/call-string.h, analyzer/program-point.h,
+ analyzer/store.h, and analyzer/region-model.h.
+ (pattern_test_state_machine::on_condition): Convert params from tree to
+ const svalue *.
+ * sm-sensitive.cc (sensitive_state_machine::on_condition): Delete.
+ * sm-signal.cc (signal_state_machine::on_condition): Delete.
+ * sm-taint.cc (taint_state_machine::on_condition): Convert params
+ from tree to const svalue *.
+ * sm.cc: Include tristate.h, selftest.h, analyzer/call-string.h,
+ analyzer/program-point.h, analyzer/store.h, and
+ analyzer/region-model.h.
+ (any_pointer_p): Add overload taking const svalue *sval.
+ * sm.h (any_pointer_p): Add overload taking const svalue *sval.
+ (state_machine::on_condition): Convert params from tree to
+ const svalue *. Provide no-op default implementation.
+ (sm_context::get_state): Add overload taking const svalue *sval.
+ (sm_context::set_next_state): Likewise.
+ (sm_context::on_transition): Likewise.
+ (sm_context::get_diagnostic_tree): Likewise.
+ * svalue.cc (svalue::all_zeroes_p): New.
+ (constant_svalue::all_zeroes_p): New.
+ (repeated_svalue::all_zeroes_p): Convert to vfunc.
+ * svalue.h (svalue::all_zeroes_p): New decl.
+ (constant_svalue::all_zeroes_p): New decl.
+ (repeated_svalue::all_zeroes_p): Convert decl to vfunc.
+
+2021-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/95006
+ * analyzer.h (class repeated_svalue): New forward decl.
+ (class bits_within_svalue): New forward decl.
+ (class sized_region): New forward decl.
+ (get_field_at_bit_offset): New forward decl.
+ * engine.cc (exploded_graph::get_or_create_node): Validate the
+ merged state.
+ (exploded_graph::maybe_process_run_of_before_supernode_enodes):
+ Validate the states at each stage.
+ * program-state.cc (program_state::validate): Validate
+ m_region_model.
+ * region-model-impl-calls.cc (region_model::impl_call_memset):
+ Replace special-case logic for handling constant sizes with
+ a call to fill_region of a sized_region with the given fill value.
+ * region-model-manager.cc (maybe_undo_optimize_bit_field_compare):
+ Drop DK_direct.
+ (region_model_manager::maybe_fold_sub_svalue): Fold element-based
+ subregions of an initial value into initial values of an element.
+ Fold subvalues of repeated svalues.
+ (region_model_manager::maybe_fold_repeated_svalue): New.
+ (region_model_manager::get_or_create_repeated_svalue): New.
+ (get_bit_range_for_field): New.
+ (get_byte_range_for_field): New.
+ (get_field_at_byte_range): New.
+ (region_model_manager::maybe_fold_bits_within_svalue): New.
+ (region_model_manager::get_or_create_bits_within): New.
+ (region_model_manager::get_sized_region): New.
+ (region_model_manager::log_stats): Update for addition of
+ m_repeated_values_map, m_bits_within_values_map, and
+ m_sized_regions.
+ * region-model.cc (region_model::validate): New.
+ (region_model::on_assignment): Drop enum binding_kind.
+ (region_model::get_initial_value_for_global): Likewise.
+ (region_model::get_rvalue_for_bits): Replace body with call to
+ get_or_create_bits_within.
+ (region_model::get_capacity): Handle RK_SIZED.
+ (region_model::set_value): Drop enum binding_kind.
+ (region_model::fill_region): New.
+ (region_model::get_representative_path_var_1): Handle RK_SIZED.
+ * region-model.h (visitor::visit_repeated_svalue): New.
+ (visitor::visit_bits_within_svalue): New.
+ (region_model_manager::get_or_create_repeated_svalue): New decl.
+ (region_model_manager::get_or_create_bits_within): New decl.
+ (region_model_manager::get_sized_region): New decl.
+ (region_model_manager::maybe_fold_repeated_svalue): New decl.
+ (region_model_manager::maybe_fold_bits_within_svalue): New decl.
+ (region_model_manager::repeated_values_map_t): New typedef.
+ (region_model_manager::m_repeated_values_map): New field.
+ (region_model_manager::bits_within_values_map_t): New typedef.
+ (region_model_manager::m_bits_within_values_map): New field.
+ (region_model_manager::m_sized_regions): New field.
+ (region_model::fill_region): New decl.
+ * region.cc (region::get_base_region): Handle RK_SIZED.
+ (region::base_region_p): Likewise.
+ (region::get_byte_size_sval): New.
+ (get_field_at_bit_offset): Make non-static.
+ (region::calc_offset): Move implementation of cases to
+ get_relative_concrete_offset vfunc implementations. Handle
+ RK_SIZED.
+ (region::get_relative_concrete_offset): New.
+ (decl_region::get_svalue_for_initializer): Drop enum binding_kind.
+ (field_region::get_relative_concrete_offset): New, from
+ region::calc_offset.
+ (element_region::get_relative_concrete_offset): Likewise.
+ (offset_region::get_relative_concrete_offset): Likewise.
+ (sized_region::accept): New.
+ (sized_region::dump_to_pp): New.
+ (sized_region::get_byte_size): New.
+ (sized_region::get_bit_size): New.
+ * region.h (enum region_kind): Add RK_SIZED.
+ (region::dyn_cast_sized_region): New.
+ (region::get_byte_size): Make virtual.
+ (region::get_bit_size): Likewise.
+ (region::get_byte_size_sval): New decl.
+ (region::get_relative_concrete_offset): New decl.
+ (field_region::get_relative_concrete_offset): New decl.
+ (element_region::get_relative_concrete_offset): Likewise.
+ (offset_region::get_relative_concrete_offset): Likewise.
+ (class sized_region): New.
+ * store.cc (binding_kind_to_string): Delete.
+ (binding_key::make): Drop enum binding_kind.
+ (binding_key::dump_to_pp): Delete.
+ (binding_key::cmp_ptrs): Drop enum binding_kind.
+ (bit_range::contains_p): New.
+ (byte_range::dump): New.
+ (byte_range::contains_p): New.
+ (byte_range::cmp): New.
+ (concrete_binding::dump_to_pp): Drop enum binding_kind.
+ (concrete_binding::cmp_ptr_ptr): Likewise.
+ (symbolic_binding::dump_to_pp): Likewise.
+ (symbolic_binding::cmp_ptr_ptr): Likewise.
+ (binding_map::apply_ctor_val_to_range): Likewise.
+ (binding_map::apply_ctor_pair_to_child_region): Likewise.
+ (binding_map::get_overlapping_bindings): New.
+ (binding_map::remove_overlapping_bindings): New.
+ (binding_cluster::validate): New.
+ (binding_cluster::bind): Drop enum binding_kind.
+ (binding_cluster::bind_compound_sval): Likewise.
+ (binding_cluster::purge_region): Likewise.
+ (binding_cluster::zero_fill_region): Reimplement in terms of...
+ (binding_cluster::fill_region): New.
+ (binding_cluster::mark_region_as_unknown): Drop enum binding_kind.
+ (binding_cluster::get_binding): Likewise.
+ (binding_cluster::get_binding_recursive): Likewise.
+ (binding_cluster::get_any_binding): Likewise.
+ (binding_cluster::maybe_get_compound_binding): Reimplement.
+ (binding_cluster::get_overlapping_bindings): Delete.
+ (binding_cluster::remove_overlapping_bindings): Reimplement in
+ terms of binding_map::remove_overlapping_bindings.
+ (binding_cluster::can_merge_p): Update for removal of
+ enum binding_kind.
+ (binding_cluster::on_unknown_fncall): Drop enum binding_kind.
+ (binding_cluster::maybe_get_simple_value): Likewise.
+ (store_manager::get_concrete_binding): Likewise.
+ (store_manager::get_symbolic_binding): Likewise.
+ (store::validate): New.
+ (store::set_value): Drop enum binding_kind.
+ (store::zero_fill_region): Reimplement in terms of...
+ (store::fill_region): New.
+ (selftest::test_binding_key_overlap): Drop enum binding_kind.
+ * store.h (enum binding_kind): Delete.
+ (binding_kind_to_string): Delete decl.
+ (binding_key::make): Drop enum binding_kind.
+ (binding_key::dump_to_pp): Make pure virtual.
+ (binding_key::get_kind): Delete.
+ (binding_key::mark_deleted): Delete.
+ (binding_key::mark_empty): Delete.
+ (binding_key::is_deleted): Delete.
+ (binding_key::is_empty): Delete.
+ (binding_key::binding_key): Delete.
+ (binding_key::impl_hash): Delete.
+ (binding_key::impl_eq): Delete.
+ (binding_key::m_kind): Delete.
+ (bit_range::get_last_bit_offset): New.
+ (bit_range::contains_p): New.
+ (byte_range::contains_p): New.
+ (byte_range::operator==): New.
+ (byte_range::get_start_byte_offset): New.
+ (byte_range::get_next_byte_offset): New.
+ (byte_range::get_last_byte_offset): New.
+ (byte_range::as_bit_range): New.
+ (byte_range::cmp): New.
+ (concrete_binding::concrete_binding): Drop enum binding_kind.
+ (concrete_binding::hash): Likewise.
+ (concrete_binding::operator==): Likewise.
+ (concrete_binding::mark_deleted): New.
+ (concrete_binding::mark_empty): New.
+ (concrete_binding::is_deleted): New.
+ (concrete_binding::is_empty): New.
+ (default_hash_traits<ana::concrete_binding>::empty_zero_p): Make false.
+ (symbolic_binding::symbolic_binding): Drop enum binding_kind.
+ (symbolic_binding::hash): Likewise.
+ (symbolic_binding::operator==): Likewise.
+ (symbolic_binding::mark_deleted): New.
+ (symbolic_binding::mark_empty): New.
+ (symbolic_binding::is_deleted): New.
+ (symbolic_binding::is_empty): New.
+ (binding_map::remove_overlapping_bindings): New decl.
+ (binding_map::get_overlapping_bindings): New decl.
+ (binding_cluster::validate): New decl.
+ (binding_cluster::bind): Drop enum binding_kind.
+ (binding_cluster::fill_region): New decl.
+ (binding_cluster::get_binding): Drop enum binding_kind.
+ (binding_cluster::get_binding_recursive): Likewise.
+ (binding_cluster::get_overlapping_bindings): Delete.
+ (store::validate): New decl.
+ (store::set_value): Drop enum binding_kind.
+ (store::fill_region): New decl.
+ (store_manager::get_concrete_binding): Drop enum binding_kind.
+ (store_manager::get_symbolic_binding): Likewise.
+ * svalue.cc (svalue::cmp_ptr): Handle SK_REPEATED and
+ SK_BITS_WITHIN.
+ (svalue::extract_bit_range): New.
+ (svalue::maybe_fold_bits_within): New.
+ (constant_svalue::maybe_fold_bits_within): New.
+ (unknown_svalue::maybe_fold_bits_within): New.
+ (unaryop_svalue::maybe_fold_bits_within): New.
+ (repeated_svalue::repeated_svalue): New.
+ (repeated_svalue::dump_to_pp): New.
+ (repeated_svalue::accept): New.
+ (repeated_svalue::all_zeroes_p): New.
+ (repeated_svalue::maybe_fold_bits_within): New.
+ (bits_within_svalue::bits_within_svalue): New.
+ (bits_within_svalue::dump_to_pp): New.
+ (bits_within_svalue::maybe_fold_bits_within): New.
+ (bits_within_svalue::accept): New.
+ (bits_within_svalue::implicitly_live_p): New.
+ (compound_svalue::maybe_fold_bits_within): New.
+ * svalue.h (enum svalue_kind): Add SK_REPEATED and SK_BITS_WITHIN.
+ (svalue::dyn_cast_repeated_svalue): New.
+ (svalue::dyn_cast_bits_within_svalue): New.
+ (svalue::extract_bit_range): New decl.
+ (svalue::maybe_fold_bits_within): New vfunc decl.
+ (region_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (region_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<region_svalue::key_t>::empty_zero_p): Make false.
+ (constant_svalue::maybe_fold_bits_within): New.
+ (unknown_svalue::maybe_fold_bits_within): New.
+ (poisoned_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (poisoned_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<poisoned_svalue::key_t>::empty_zero_p): Make
+ false.
+ (setjmp_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (setjmp_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<setjmp_svalue::key_t>::empty_zero_p): Make
+ false.
+ (unaryop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (unaryop_svalue::key_t::is_empty): Likewise.
+ (unaryop_svalue::maybe_fold_bits_within): New.
+ (default_hash_traits<unaryop_svalue::key_t>::empty_zero_p): Make
+ false.
+ (binop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (binop_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<binop_svalue::key_t>::empty_zero_p): Make
+ false.
+ (sub_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (sub_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<sub_svalue::key_t>::empty_zero_p): Make
+ false.
+ (class repeated_svalue): New.
+ (is_a_helper <const repeated_svalue *>::test): New.
+ (struct default_hash_traits<repeated_svalue::key_t>): New.
+ (class bits_within_svalue): New.
+ (is_a_helper <const bits_within_svalue *>::test): New.
+ (struct default_hash_traits<bits_within_svalue::key_t>): New.
+ (widening_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (widening_svalue::key_t::is_empty): Likewise.
+ (default_hash_traits<widening_svalue::key_t>::empty_zero_p): Make
+ false.
+ (compound_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
+ (compound_svalue::key_t::is_empty): Likewise.
+ (compound_svalue::maybe_fold_bits_within): New.
+ (default_hash_traits<compound_svalue::key_t>::empty_zero_p): Make
+ false.
+
2021-06-28 David Malcolm <dmalcolm@redhat.com>
* analyzer.h (byte_offset_t): New typedef.
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index f06b68c..02830e4 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -46,6 +46,8 @@ class svalue;
class unaryop_svalue;
class binop_svalue;
class sub_svalue;
+ class repeated_svalue;
+ class bits_within_svalue;
class unmergeable_svalue;
class placeholder_svalue;
class widening_svalue;
@@ -60,6 +62,7 @@ class region;
class symbolic_region;
class element_region;
class offset_region;
+ class sized_region;
class cast_region;
class field_region;
class string_region;
@@ -147,6 +150,8 @@ typedef offset_int byte_size_t;
extern bool int_size_in_bits (const_tree type, bit_size_t *out);
+extern tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset);
+
/* The location of a region expressesd as an offset relative to a
base region. */
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 7eb4ed8..b7d263b 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1377,6 +1377,14 @@ struct null_assignment_sm_context : public sm_context
return current;
}
+ state_machine::state_t get_state (const gimple *stmt ATTRIBUTE_UNUSED,
+ const svalue *sval) FINAL OVERRIDE
+ {
+ const sm_state_map *old_smap = m_old_state->m_checker_states[m_sm_idx];
+ state_machine::state_t current = old_smap->get_state (sval, m_ext_state);
+ return current;
+ }
+
void set_next_state (const gimple *stmt,
tree var,
state_machine::state_t to,
@@ -1401,6 +1409,28 @@ struct null_assignment_sm_context : public sm_context
*m_new_state));
}
+ void set_next_state (const gimple *stmt,
+ const svalue *sval,
+ state_machine::state_t to,
+ tree origin ATTRIBUTE_UNUSED) FINAL OVERRIDE
+ {
+ state_machine::state_t from = get_state (stmt, sval);
+ if (from != m_sm.get_start_state ())
+ return;
+
+ const supernode *supernode = m_point->get_supernode ();
+ int stack_depth = m_point->get_stack_depth ();
+
+ m_emission_path->add_event (new state_change_event (supernode,
+ m_stmt,
+ stack_depth,
+ m_sm,
+ sval,
+ from, to,
+ NULL,
+ *m_new_state));
+ }
+
void warn (const supernode *, const gimple *,
tree, pending_diagnostic *d) FINAL OVERRIDE
{
@@ -1412,6 +1442,11 @@ struct null_assignment_sm_context : public sm_context
return expr;
}
+ tree get_diagnostic_tree (const svalue *sval) FINAL OVERRIDE
+ {
+ return m_new_state->m_region_model->get_representative_tree (sval);
+ }
+
state_machine::state_t get_global_state () const FINAL OVERRIDE
{
return 0;
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index f322fdb..01b83a4 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -245,6 +245,16 @@ public:
= m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ());
return current;
}
+ state_machine::state_t get_state (const gimple *stmt ATTRIBUTE_UNUSED,
+ const svalue *sval)
+ {
+ logger * const logger = get_logger ();
+ LOG_FUNC (logger);
+ state_machine::state_t current
+ = m_old_smap->get_state (sval, m_eg.get_ext_state ());
+ return current;
+ }
+
void set_next_state (const gimple *stmt,
tree var,
@@ -280,6 +290,41 @@ public:
to, origin_new_sval, m_eg.get_ext_state ());
}
+ void set_next_state (const gimple *stmt,
+ const svalue *sval,
+ state_machine::state_t to,
+ tree origin)
+ {
+ logger * const logger = get_logger ();
+ LOG_FUNC (logger);
+ impl_region_model_context old_ctxt
+ (m_eg, m_enode_for_diag, NULL, NULL/*m_enode->get_state ()*/,
+ NULL, stmt);
+
+ impl_region_model_context new_ctxt (m_eg, m_enode_for_diag,
+ m_old_state, m_new_state,
+ NULL,
+ stmt);
+ const svalue *origin_new_sval
+ = m_new_state->m_region_model->get_rvalue (origin, &new_ctxt);
+
+ state_machine::state_t current
+ = m_old_smap->get_state (sval, m_eg.get_ext_state ());
+ if (logger)
+ {
+ logger->start_log_line ();
+ logger->log_partial ("%s: state transition of ",
+ m_sm.get_name ());
+ sval->dump_to_pp (logger->get_printer (), true);
+ logger->log_partial (": %s -> %s",
+ current->get_name (),
+ to->get_name ());
+ logger->end_log_line ();
+ }
+ m_new_smap->set_state (m_new_state->m_region_model, sval,
+ to, origin_new_sval, m_eg.get_ext_state ());
+ }
+
void warn (const supernode *snode, const gimple *stmt,
tree var, pending_diagnostic *d) FINAL OVERRIDE
{
@@ -323,6 +368,11 @@ public:
return expr;
}
+ tree get_diagnostic_tree (const svalue *sval) FINAL OVERRIDE
+ {
+ return m_new_state->m_region_model->get_representative_tree (sval);
+ }
+
state_machine::state_t get_global_state () const FINAL OVERRIDE
{
return m_old_state->m_checker_states[m_sm_idx]->get_global_state ();
@@ -654,7 +704,9 @@ impl_region_model_context::on_state_leak (const state_machine &sm,
state transitions. */
void
-impl_region_model_context::on_condition (tree lhs, enum tree_code op, tree rhs)
+impl_region_model_context::on_condition (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs)
{
int sm_idx;
sm_state_map *smap;
@@ -2275,6 +2327,7 @@ exploded_graph::get_or_create_node (const program_point &point,
if (pruned_state.can_merge_with_p (existing_state, point,
&merged_state))
{
+ merged_state.validate (m_ext_state);
if (logger)
logger->log ("merging new state with that of EN: %i",
existing_enode->m_index);
@@ -2794,6 +2847,7 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode)
items.quick_push (it);
const program_state &state = iter_enode->get_state ();
program_state *next_state = &it->m_processed_state;
+ next_state->validate (m_ext_state);
const program_point &iter_point = iter_enode->get_point ();
if (const superedge *iter_sedge = iter_point.get_from_edge ())
{
@@ -2807,6 +2861,7 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode)
next_state->m_region_model->update_for_phis
(snode, last_cfg_superedge, &ctxt);
}
+ next_state->validate (m_ext_state);
}
/* Attempt to partition the items into a set of merged states.
@@ -2823,10 +2878,12 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode)
unsigned iter_merger_idx;
FOR_EACH_VEC_ELT (merged_states, iter_merger_idx, merged_state)
{
+ merged_state->validate (m_ext_state);
program_state merge (m_ext_state);
if (it_state.can_merge_with_p (*merged_state, next_point, &merge))
{
*merged_state = merge;
+ merged_state->validate (m_ext_state);
it->m_merger_idx = iter_merger_idx;
if (logger)
logger->log ("reusing merger state %i for item %i (EN: %i)",
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index eb1baef..2d25e5e 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -59,7 +59,9 @@ class impl_region_model_context : public region_model_context
const svalue *sval,
state_machine::state_t state);
- void on_condition (tree lhs, enum tree_code op, tree rhs) FINAL OVERRIDE;
+ void on_condition (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs) FINAL OVERRIDE;
void on_unknown_change (const svalue *sval, bool is_mutable) FINAL OVERRIDE;
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 67dd785..6d60c04 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -1142,6 +1142,7 @@ program_state::validate (const extrinsic_state &ext_state) const
#endif
gcc_assert (m_checker_states.length () == ext_state.get_num_checkers ());
+ m_region_model->validate ();
}
static void
diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc
index 099520a..466d397 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -389,36 +389,15 @@ region_model::impl_call_memset (const call_details &cd)
const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
cd.get_ctxt ());
- if (tree num_bytes = num_bytes_sval->maybe_get_constant ())
- {
- /* "memset" of zero size is a no-op. */
- if (zerop (num_bytes))
- return true;
-
- /* Set with known amount. */
- byte_size_t reg_size;
- if (dest_reg->get_byte_size (&reg_size))
- {
- /* Check for an exact size match. */
- if (reg_size == wi::to_offset (num_bytes))
- {
- if (tree cst = fill_value_sval->maybe_get_constant ())
- {
- if (zerop (cst))
- {
- zero_fill_region (dest_reg);
- return true;
- }
- }
- }
- }
- }
-
- check_for_writable_region (dest_reg, cd.get_ctxt ());
-
- /* Otherwise, mark region's contents as unknown. */
- mark_region_as_unknown (dest_reg, cd.get_uncertainty ());
- return false;
+ const svalue *fill_value_u8
+ = m_mgr->get_or_create_cast (unsigned_char_type_node, fill_value_sval);
+
+ const region *sized_dest_reg = m_mgr->get_sized_region (dest_reg,
+ NULL_TREE,
+ num_bytes_sval);
+ check_for_writable_region (sized_dest_reg, cd.get_ctxt ());
+ fill_region (sized_dest_reg, fill_value_u8);
+ return true;
}
/* Handle the on_call_pre part of "operator new". */
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index 1ee6663..55acb90 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -477,7 +477,7 @@ maybe_undo_optimize_bit_field_compare (tree type,
bound_bits = bit_range (BITS_PER_UNIT - bits.get_next_bit_offset (),
bits.m_size_in_bits);
const concrete_binding *conc
- = get_store_manager ()->get_concrete_binding (bound_bits, BK_direct);
+ = get_store_manager ()->get_concrete_binding (bound_bits);
const svalue *sval = map.get (conc);
if (!sval)
return NULL;
@@ -686,13 +686,13 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
return get_or_create_cast (type, char_sval);
}
- /* SUB(INIT(r)).FIELD -> INIT(r.FIELD)
- i.e.
- Subvalue(InitialValue(R1), FieldRegion(R2, F))
- -> InitialValue(FieldRegion(R1, F)). */
if (const initial_svalue *init_sval
- = parent_svalue->dyn_cast_initial_svalue ())
+ = parent_svalue->dyn_cast_initial_svalue ())
{
+ /* SUB(INIT(r)).FIELD -> INIT(r.FIELD)
+ i.e.
+ Subvalue(InitialValue(R1), FieldRegion(R2, F))
+ -> InitialValue(FieldRegion(R1, F)). */
if (const field_region *field_reg = subregion->dyn_cast_field_region ())
{
const region *field_reg_new
@@ -700,8 +700,24 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
field_reg->get_field ());
return get_or_create_initial_value (field_reg_new);
}
+ /* SUB(INIT(r)[ELEMENT] -> INIT(e[ELEMENT])
+ i.e.
+ Subvalue(InitialValue(R1), ElementRegion(R2, IDX))
+ -> InitialValue(ElementRegion(R1, IDX)). */
+ if (const element_region *element_reg = subregion->dyn_cast_element_region ())
+ {
+ const region *element_reg_new
+ = get_element_region (init_sval->get_region (),
+ element_reg->get_type (),
+ element_reg->get_index ());
+ return get_or_create_initial_value (element_reg_new);
+ }
}
+ if (const repeated_svalue *repeated_sval
+ = parent_svalue->dyn_cast_repeated_svalue ())
+ return get_or_create_cast (type, repeated_sval->get_inner_svalue ());
+
return NULL;
}
@@ -727,6 +743,255 @@ region_model_manager::get_or_create_sub_svalue (tree type,
return sub_sval;
}
+/* Subroutine of region_model_manager::get_or_create_repeated_svalue.
+ Return a folded svalue, or NULL. */
+
+const svalue *
+region_model_manager::maybe_fold_repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue)
+{
+ /* If INNER_SVALUE is the same size as OUTER_SIZE,
+ turn into simply a cast. */
+ if (tree cst_outer_num_bytes = outer_size->maybe_get_constant ())
+ {
+ HOST_WIDE_INT num_bytes_inner_svalue
+ = int_size_in_bytes (inner_svalue->get_type ());
+ if (num_bytes_inner_svalue != -1)
+ if (num_bytes_inner_svalue
+ == (HOST_WIDE_INT)tree_to_uhwi (cst_outer_num_bytes))
+ {
+ if (type)
+ return get_or_create_cast (type, inner_svalue);
+ else
+ return inner_svalue;
+ }
+ }
+
+ /* Handle zero-fill of a specific type. */
+ if (tree cst = inner_svalue->maybe_get_constant ())
+ if (zerop (cst) && type)
+ return get_or_create_cast (type, inner_svalue);
+
+ return NULL;
+}
+
+/* Return the svalue * of type TYPE in which INNER_SVALUE is repeated
+ enough times to be of size OUTER_SIZE, creating it if necessary.
+ e.g. for filling buffers with a constant value. */
+
+const svalue *
+region_model_manager::get_or_create_repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue)
+{
+ if (const svalue *folded
+ = maybe_fold_repeated_svalue (type, outer_size, inner_svalue))
+ return folded;
+
+ repeated_svalue::key_t key (type, outer_size, inner_svalue);
+ if (repeated_svalue **slot = m_repeated_values_map.get (key))
+ return *slot;
+ repeated_svalue *repeated_sval
+ = new repeated_svalue (type, outer_size, inner_svalue);
+ RETURN_UNKNOWN_IF_TOO_COMPLEX (repeated_sval);
+ m_repeated_values_map.put (key, repeated_sval);
+ return repeated_sval;
+}
+
+/* Attempt to get the bit_range for FIELD within a RECORD_TYPE.
+ Return true and write the result to OUT if successful.
+ Return false otherwise. */
+
+static bool
+get_bit_range_for_field (tree field, bit_range *out)
+{
+ bit_size_t bit_size;
+ if (!int_size_in_bits (TREE_TYPE (field), &bit_size))
+ return false;
+ int field_bit_offset = int_bit_position (field);
+ *out = bit_range (field_bit_offset, bit_size);
+ return true;
+}
+
+/* Attempt to get the byte_range for FIELD within a RECORD_TYPE.
+ Return true and write the result to OUT if successful.
+ Return false otherwise. */
+
+static bool
+get_byte_range_for_field (tree field, byte_range *out)
+{
+ bit_range field_bits (0, 0);
+ if (!get_bit_range_for_field (field, &field_bits))
+ return false;
+ return field_bits.as_byte_range (out);
+}
+
+/* Attempt to determine if there is a specific field within RECORD_TYPE
+ at BYTES. If so, return it, and write the location of BYTES relative
+ to the field to *OUT_RANGE_WITHIN_FIELD.
+ Otherwise, return NULL_TREE.
+ For example, given:
+ struct foo { uint32 a; uint32; b};
+ and
+ bytes = {bytes 6-7} (of foo)
+ we have bytes 3-4 of field b. */
+
+static tree
+get_field_at_byte_range (tree record_type, const byte_range &bytes,
+ byte_range *out_range_within_field)
+{
+ bit_offset_t bit_offset = bytes.m_start_byte_offset * BITS_PER_UNIT;
+
+ tree field = get_field_at_bit_offset (record_type, bit_offset);
+ if (!field)
+ return NULL_TREE;
+
+ byte_range field_bytes (0,0);
+ if (!get_byte_range_for_field (field, &field_bytes))
+ return NULL_TREE;
+
+ /* Is BYTES fully within field_bytes? */
+ byte_range bytes_within_field (0,0);
+ if (!field_bytes.contains_p (bytes, &bytes_within_field))
+ return NULL_TREE;
+
+ *out_range_within_field = bytes_within_field;
+ return field;
+}
+
+/* Subroutine of region_model_manager::get_or_create_bits_within.
+ Return a folded svalue, or NULL. */
+
+const svalue *
+region_model_manager::maybe_fold_bits_within_svalue (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue)
+{
+ tree inner_type = inner_svalue->get_type ();
+ /* Fold:
+ BITS_WITHIN ((0, sizeof (VAL), VAL))
+ to:
+ CAST(TYPE, VAL). */
+ if (bits.m_start_bit_offset == 0 && inner_type)
+ {
+ bit_size_t inner_type_size;
+ if (int_size_in_bits (inner_type, &inner_type_size))
+ if (inner_type_size == bits.m_size_in_bits)
+ {
+ if (type)
+ return get_or_create_cast (type, inner_svalue);
+ else
+ return inner_svalue;
+ }
+ }
+
+ /* Kind-specific folding. */
+ if (const svalue *sval
+ = inner_svalue->maybe_fold_bits_within (type, bits, this))
+ return sval;
+
+ byte_range bytes (0,0);
+ if (bits.as_byte_range (&bytes) && inner_type)
+ switch (TREE_CODE (inner_type))
+ {
+ default:
+ break;
+ case ARRAY_TYPE:
+ {
+ /* Fold:
+ BITS_WITHIN (range, KIND(REG))
+ to:
+ BITS_WITHIN (range - offsetof(ELEMENT), KIND(REG.ELEMENT))
+ if range1 is a byte-range fully within one ELEMENT. */
+ tree element_type = TREE_TYPE (inner_type);
+ HOST_WIDE_INT element_byte_size
+ = int_size_in_bytes (element_type);
+ if (element_byte_size > 0)
+ {
+ HOST_WIDE_INT start_idx
+ = (bytes.get_start_byte_offset ().to_shwi ()
+ / element_byte_size);
+ HOST_WIDE_INT last_idx
+ = (bytes.get_last_byte_offset ().to_shwi ()
+ / element_byte_size);
+ if (start_idx == last_idx)
+ {
+ if (const initial_svalue *initial_sval
+ = inner_svalue->dyn_cast_initial_svalue ())
+ {
+ bit_offset_t start_of_element
+ = start_idx * element_byte_size * BITS_PER_UNIT;
+ bit_range bits_within_element
+ (bits.m_start_bit_offset - start_of_element,
+ bits.m_size_in_bits);
+ const svalue *idx_sval
+ = get_or_create_int_cst (integer_type_node, start_idx);
+ const region *element_reg =
+ get_element_region (initial_sval->get_region (),
+ element_type, idx_sval);
+ const svalue *element_reg_sval
+ = get_or_create_initial_value (element_reg);
+ return get_or_create_bits_within (type,
+ bits_within_element,
+ element_reg_sval);
+ }
+ }
+ }
+ }
+ break;
+ case RECORD_TYPE:
+ {
+ /* Fold:
+ BYTES_WITHIN (range, KIND(REG))
+ to:
+ BYTES_WITHIN (range - offsetof(FIELD), KIND(REG.FIELD))
+ if range1 is fully within FIELD. */
+ byte_range bytes_within_field (0, 0);
+ if (tree field = get_field_at_byte_range (inner_type, bytes,
+ &bytes_within_field))
+ {
+ if (const initial_svalue *initial_sval
+ = inner_svalue->dyn_cast_initial_svalue ())
+ {
+ const region *field_reg =
+ get_field_region (initial_sval->get_region (), field);
+ const svalue *initial_reg_sval
+ = get_or_create_initial_value (field_reg);
+ return get_or_create_bits_within
+ (type,
+ bytes_within_field.as_bit_range (),
+ initial_reg_sval);
+ }
+ }
+ }
+ break;
+ }
+ return NULL;
+}
+
+/* Return the svalue * of type TYPE for extracting BITS from INNER_SVALUE,
+ creating it if necessary. */
+
+const svalue *
+region_model_manager::get_or_create_bits_within (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue)
+{
+ if (const svalue *folded
+ = maybe_fold_bits_within_svalue (type, bits, inner_svalue))
+ return folded;
+
+ bits_within_svalue::key_t key (type, bits, inner_svalue);
+ if (bits_within_svalue **slot = m_bits_within_values_map.get (key))
+ return *slot;
+ bits_within_svalue *bits_within_sval
+ = new bits_within_svalue (type, bits, inner_svalue);
+ RETURN_UNKNOWN_IF_TOO_COMPLEX (bits_within_sval);
+ m_bits_within_values_map.put (key, bits_within_sval);
+ return bits_within_sval;
+}
+
/* Return the svalue * that decorates ARG as being unmergeable,
creating it if necessary. */
@@ -966,6 +1231,38 @@ region_model_manager::get_offset_region (const region *parent,
return offset_reg;
}
+/* Return the region that describes accessing the subregion of type
+ TYPE of size BYTE_SIZE_SVAL within PARENT, creating it if necessary. */
+
+const region *
+region_model_manager::get_sized_region (const region *parent,
+ tree type,
+ const svalue *byte_size_sval)
+{
+ if (byte_size_sval->get_type () != size_type_node)
+ byte_size_sval = get_or_create_cast (size_type_node, byte_size_sval);
+
+ /* If PARENT is already that size, return it. */
+ const svalue *parent_byte_size_sval = parent->get_byte_size_sval (this);
+ if (tree parent_size_cst = parent_byte_size_sval->maybe_get_constant ())
+ if (tree size_cst = byte_size_sval->maybe_get_constant ())
+ {
+ tree comparison
+ = fold_binary (EQ_EXPR, boolean_type_node, parent_size_cst, size_cst);
+ if (comparison == boolean_true_node)
+ return parent;
+ }
+
+ sized_region::key_t key (parent, type, byte_size_sval);
+ if (sized_region *reg = m_sized_regions.get (key))
+ return reg;
+
+ sized_region *sized_reg
+ = new sized_region (alloc_region_id (), parent, type, byte_size_sval);
+ m_sized_regions.put (key, sized_reg);
+ return sized_reg;
+}
+
/* Return the region that describes accessing PARENT_REGION as if
it were of type TYPE, creating it if necessary. */
@@ -1180,6 +1477,9 @@ region_model_manager::log_stats (logger *logger, bool show_objs) const
log_uniq_map (logger, show_objs, "unaryop_svalue", m_unaryop_values_map);
log_uniq_map (logger, show_objs, "binop_svalue", m_binop_values_map);
log_uniq_map (logger, show_objs, "sub_svalue", m_sub_values_map);
+ log_uniq_map (logger, show_objs, "repeated_svalue", m_repeated_values_map);
+ log_uniq_map (logger, show_objs, "bits_within_svalue",
+ m_bits_within_values_map);
log_uniq_map (logger, show_objs, "unmergeable_svalue",
m_unmergeable_values_map);
log_uniq_map (logger, show_objs, "widening_svalue", m_widening_values_map);
@@ -1198,6 +1498,7 @@ region_model_manager::log_stats (logger *logger, bool show_objs) const
log_uniq_map (logger, show_objs, "field_region", m_field_regions);
log_uniq_map (logger, show_objs, "element_region", m_element_regions);
log_uniq_map (logger, show_objs, "offset_region", m_offset_regions);
+ log_uniq_map (logger, show_objs, "sized_region", m_sized_regions);
log_uniq_map (logger, show_objs, "cast_region", m_cast_regions);
log_uniq_map (logger, show_objs, "frame_region", m_frame_regions);
log_uniq_map (logger, show_objs, "symbolic_region", m_symbolic_regions);
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index ee11e82..acbbd11 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -393,6 +393,14 @@ region_model::debug () const
dump (true);
}
+/* Assert that this object is valid. */
+
+void
+region_model::validate () const
+{
+ m_store.validate ();
+}
+
/* Canonicalize the store and constraints, to maximize the chance of
equality between region_model instances. */
@@ -847,11 +855,9 @@ region_model::on_assignment (const gassign *assign, region_model_context *ctxt)
case STRING_CST:
{
/* e.g. "struct s2 x = {{'A', 'B', 'C', 'D'}};". */
- /* Add a default binding, rather than a direct one, so that array
- access will "inherit" the individual chars. */
const svalue *rhs_sval = get_rvalue (rhs1, ctxt);
m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
- BK_default, ctxt ? ctxt->get_uncertainty () : NULL);
+ ctxt ? ctxt->get_uncertainty () : NULL);
}
break;
}
@@ -875,12 +881,23 @@ bool
region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
bool *out_terminate_path)
{
+ call_details cd (call, this, ctxt);
+
bool unknown_side_effects = false;
- if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
+ if (gimple_call_internal_p (call))
{
- call_details cd (call, this, ctxt);
+ switch (gimple_call_internal_fn (call))
+ {
+ default:
+ break;
+ case IFN_BUILTIN_EXPECT:
+ return impl_call_builtin_expect (cd);
+ }
+ }
+ if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
+ {
/* The various impl_call_* member functions are implemented
in region-model-impl-calls.cc.
Having them split out into separate functions makes it easier
@@ -952,16 +969,6 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
on the return value. */
break;
}
- else if (gimple_call_internal_p (call))
- switch (gimple_call_internal_fn (call))
- {
- default:
- if (!DECL_PURE_P (callee_fndecl))
- unknown_side_effects = true;
- break;
- case IFN_BUILTIN_EXPECT:
- return impl_call_builtin_expect (cd);
- }
else if (is_named_call_p (callee_fndecl, "malloc", call, 1))
return impl_call_malloc (cd);
else if (is_named_call_p (callee_fndecl, "calloc", call, 2))
@@ -1662,8 +1669,7 @@ region_model::get_initial_value_for_global (const region *reg) const
{
/* Get the value for REG within base_reg_init. */
binding_cluster c (base_reg);
- c.bind (m_mgr->get_store_manager (), base_reg, base_reg_init,
- BK_direct);
+ c.bind (m_mgr->get_store_manager (), base_reg, base_reg_init);
const svalue *sval
= c.get_any_binding (m_mgr->get_store_manager (), reg);
if (sval)
@@ -1854,45 +1860,7 @@ region_model::get_rvalue_for_bits (tree type,
const bit_range &bits) const
{
const svalue *sval = get_store_value (reg);
- if (const compound_svalue *compound_sval = sval->dyn_cast_compound_svalue ())
- {
- const binding_map &map = compound_sval->get_map ();
- binding_map result_map;
- for (auto iter : map)
- {
- const binding_key *key = iter.first;
- if (const concrete_binding *conc_key
- = key->dyn_cast_concrete_binding ())
- {
- /* Ignore concrete bindings outside BITS. */
- if (!conc_key->get_bit_range ().intersects_p (bits))
- continue;
- if ((conc_key->get_start_bit_offset ()
- < bits.get_start_bit_offset ())
- || (conc_key->get_next_bit_offset ()
- > bits.get_next_bit_offset ()))
- {
- /* If we have any concrete keys that aren't fully within BITS,
- then bail out. */
- return m_mgr->get_or_create_unknown_svalue (type);
- }
- const concrete_binding *offset_conc_key
- = m_mgr->get_store_manager ()->get_concrete_binding
- (conc_key->get_start_bit_offset ()
- - bits.get_start_bit_offset (),
- conc_key->get_size_in_bits (),
- conc_key->get_kind ());
- const svalue *sval = iter.second;
- result_map.put (offset_conc_key, sval);
- }
- else
- /* If we have any symbolic keys we can't get it as bits. */
- return m_mgr->get_or_create_unknown_svalue (type);
- }
- return m_mgr->get_or_create_compound_svalue (type, result_map);
- }
-
- return m_mgr->get_or_create_unknown_svalue (type);
+ return m_mgr->get_or_create_bits_within (type, bits, sval);
}
/* A subclass of pending_diagnostic for complaining about writes to
@@ -2035,6 +2003,10 @@ region_model::get_capacity (const region *reg) const
}
}
break;
+ case RK_SIZED:
+ /* Look through sized regions to get at the capacity
+ of the underlying regions. */
+ return get_capacity (reg->get_parent_region ());
}
if (const svalue *recorded = get_dynamic_extents (reg))
@@ -2056,7 +2028,7 @@ region_model::set_value (const region *lhs_reg, const svalue *rhs_sval,
check_for_writable_region (lhs_reg, ctxt);
m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
- BK_direct, ctxt ? ctxt->get_uncertainty () : NULL);
+ ctxt ? ctxt->get_uncertainty () : NULL);
}
/* Set the value of the region given by LHS to the value given by RHS. */
@@ -2087,6 +2059,14 @@ region_model::purge_region (const region *reg)
m_store.purge_region (m_mgr->get_store_manager(), reg);
}
+/* Fill REG with SVAL. */
+
+void
+region_model::fill_region (const region *reg, const svalue *sval)
+{
+ m_store.fill_region (m_mgr->get_store_manager(), reg, sval);
+}
+
/* Zero-fill REG. */
void
@@ -2272,6 +2252,123 @@ region_model::compare_initial_and_pointer (const initial_svalue *init,
return tristate::TS_UNKNOWN;
}
+/* Handle various constraints of the form:
+ LHS: ((bool)INNER_LHS INNER_OP INNER_RHS))
+ OP : == or !=
+ RHS: zero
+ and (with a cast):
+ LHS: CAST([long]int, ((bool)INNER_LHS INNER_OP INNER_RHS))
+ OP : == or !=
+ RHS: zero
+ by adding constraints for INNER_LHS INNEROP INNER_RHS.
+
+ Return true if this function can fully handle the constraint; if
+ so, add the implied constraint(s) and write true to *OUT if they
+ are consistent with existing constraints, or write false to *OUT
+ if they contradicts existing constraints.
+
+ Return false for cases that this function doeesn't know how to handle.
+
+ For example, if we're checking a stored conditional, we'll have
+ something like:
+ LHS: CAST(long int, (&HEAP_ALLOCATED_REGION(8)!=(int *)0B))
+ OP : NE_EXPR
+ RHS: zero
+ which this function can turn into an add_constraint of:
+ (&HEAP_ALLOCATED_REGION(8) != (int *)0B)
+
+ Similarly, optimized && and || conditionals lead to e.g.
+ if (p && q)
+ becoming gimple like this:
+ _1 = p_6 == 0B;
+ _2 = q_8 == 0B
+ _3 = _1 | _2
+ On the "_3 is false" branch we can have constraints of the form:
+ ((&HEAP_ALLOCATED_REGION(8)!=(int *)0B)
+ | (&HEAP_ALLOCATED_REGION(10)!=(int *)0B))
+ == 0
+ which implies that both _1 and _2 are false,
+ which this function can turn into a pair of add_constraints of
+ (&HEAP_ALLOCATED_REGION(8)!=(int *)0B)
+ and:
+ (&HEAP_ALLOCATED_REGION(10)!=(int *)0B). */
+
+bool
+region_model::add_constraints_from_binop (const svalue *outer_lhs,
+ enum tree_code outer_op,
+ const svalue *outer_rhs,
+ bool *out,
+ region_model_context *ctxt)
+{
+ while (const svalue *cast = outer_lhs->maybe_undo_cast ())
+ outer_lhs = cast;
+ const binop_svalue *binop_sval = outer_lhs->dyn_cast_binop_svalue ();
+ if (!binop_sval)
+ return false;
+ if (!outer_rhs->all_zeroes_p ())
+ return false;
+
+ const svalue *inner_lhs = binop_sval->get_arg0 ();
+ enum tree_code inner_op = binop_sval->get_op ();
+ const svalue *inner_rhs = binop_sval->get_arg1 ();
+
+ if (outer_op != NE_EXPR && outer_op != EQ_EXPR)
+ return false;
+
+ /* We have either
+ - "OUTER_LHS != false" (i.e. OUTER is true), or
+ - "OUTER_LHS == false" (i.e. OUTER is false). */
+ bool is_true = outer_op == NE_EXPR;
+
+ switch (inner_op)
+ {
+ default:
+ return false;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ {
+ /* ...and "(inner_lhs OP inner_rhs) == 0"
+ then (inner_lhs OP inner_rhs) must have the same
+ logical value as LHS. */
+ if (!is_true)
+ inner_op = invert_tree_comparison (inner_op, false /* honor_nans */);
+ *out = add_constraint (inner_lhs, inner_op, inner_rhs, ctxt);
+ return true;
+ }
+ break;
+
+ case BIT_AND_EXPR:
+ if (is_true)
+ {
+ /* ...and "(inner_lhs & inner_rhs) != 0"
+ then both inner_lhs and inner_rhs must be true. */
+ const svalue *false_sval
+ = m_mgr->get_or_create_constant_svalue (boolean_false_node);
+ bool sat1 = add_constraint (inner_lhs, NE_EXPR, false_sval, ctxt);
+ bool sat2 = add_constraint (inner_rhs, NE_EXPR, false_sval, ctxt);
+ *out = sat1 && sat2;
+ return true;
+ }
+ return false;
+
+ case BIT_IOR_EXPR:
+ if (!is_true)
+ {
+ /* ...and "(inner_lhs | inner_rhs) == 0"
+ i.e. "(inner_lhs | inner_rhs)" is false
+ then both inner_lhs and inner_rhs must be false. */
+ const svalue *false_sval
+ = m_mgr->get_or_create_constant_svalue (boolean_false_node);
+ bool sat1 = add_constraint (inner_lhs, EQ_EXPR, false_sval, ctxt);
+ bool sat2 = add_constraint (inner_rhs, EQ_EXPR, false_sval, ctxt);
+ *out = sat1 && sat2;
+ return true;
+ }
+ return false;
+ }
+}
+
/* Attempt to add the constraint "LHS OP RHS" to this region_model.
If it is consistent with existing constraints, add it, and return true.
Return false if it contradicts existing constraints.
@@ -2289,7 +2386,21 @@ region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
const svalue *lhs_sval = get_rvalue (lhs, ctxt);
const svalue *rhs_sval = get_rvalue (rhs, ctxt);
- tristate t_cond = eval_condition (lhs_sval, op, rhs_sval);
+ return add_constraint (lhs_sval, op, rhs_sval, ctxt);
+}
+
+/* Attempt to add the constraint "LHS OP RHS" to this region_model.
+ If it is consistent with existing constraints, add it, and return true.
+ Return false if it contradicts existing constraints.
+ Use CTXT for reporting any diagnostics associated with the accesses. */
+
+bool
+region_model::add_constraint (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs,
+ region_model_context *ctxt)
+{
+ tristate t_cond = eval_condition (lhs, op, rhs);
/* If we already have the condition, do nothing. */
if (t_cond.is_true ())
@@ -2300,10 +2411,12 @@ region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
if (t_cond.is_false ())
return false;
- /* Store the constraint. */
- m_constraints->add_constraint (lhs_sval, op, rhs_sval);
+ bool out;
+ if (add_constraints_from_binop (lhs, op, rhs, &out, ctxt))
+ return out;
- add_any_constraints_from_ssa_def_stmt (lhs, op, rhs, ctxt);
+ /* Store the constraint. */
+ m_constraints->add_constraint (lhs, op, rhs);
/* Notify the context, if any. This exists so that the state machines
in a program_state can be notified about the condition, and so can
@@ -2314,9 +2427,10 @@ region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
/* If we have &REGION == NULL, then drop dynamic extents for REGION (for
the case where REGION is heap-allocated and thus could be NULL). */
- if (op == EQ_EXPR && zerop (rhs))
- if (const region_svalue *region_sval = lhs_sval->dyn_cast_region_svalue ())
- unset_dynamic_extents (region_sval->get_pointee ());
+ if (tree rhs_cst = rhs->maybe_get_constant ())
+ if (op == EQ_EXPR && zerop (rhs_cst))
+ if (const region_svalue *region_sval = lhs->dyn_cast_region_svalue ())
+ unset_dynamic_extents (region_sval->get_pointee ());
return true;
}
@@ -2335,137 +2449,6 @@ region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
return sat;
}
-/* Subroutine of region_model::add_constraint for handling optimized
- && and || conditionals.
-
- If we have an SSA_NAME for a boolean compared against 0,
- look at anything implied by the def stmt and call add_constraint
- for it (which could recurse).
-
- For example, if we have
- _1 = p_6 == 0B;
- _2 = p_8 == 0B
- _3 = _1 | _2
- and add the constraint
- (_3 == 0),
- then the def stmt for _3 implies that _1 and _2 are both false,
- and hence we can add the constraints:
- p_6 != 0B
- p_8 != 0B. */
-
-void
-region_model::add_any_constraints_from_ssa_def_stmt (tree lhs,
- enum tree_code op,
- tree rhs,
- region_model_context *ctxt)
-{
- if (TREE_CODE (lhs) != SSA_NAME)
- return;
-
- if (!zerop (rhs))
- return;
-
- if (op != NE_EXPR && op != EQ_EXPR)
- return;
-
- gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
- if (const gassign *assign = dyn_cast<gassign *> (def_stmt))
- add_any_constraints_from_gassign (op, rhs, assign, ctxt);
- else if (gcall *call = dyn_cast<gcall *> (def_stmt))
- add_any_constraints_from_gcall (op, rhs, call, ctxt);
-}
-
-/* Add any constraints for an SSA_NAME defined by ASSIGN
- where the result OP RHS. */
-
-void
-region_model::add_any_constraints_from_gassign (enum tree_code op,
- tree rhs,
- const gassign *assign,
- region_model_context *ctxt)
-{
- /* We have either
- - "LHS != false" (i.e. LHS is true), or
- - "LHS == false" (i.e. LHS is false). */
- bool is_true = op == NE_EXPR;
-
- enum tree_code rhs_code = gimple_assign_rhs_code (assign);
-
- switch (rhs_code)
- {
- default:
- break;
-
- case NOP_EXPR:
- case VIEW_CONVERT_EXPR:
- {
- add_constraint (gimple_assign_rhs1 (assign), op, rhs, ctxt);
- }
- break;
-
- case BIT_AND_EXPR:
- {
- if (is_true)
- {
- /* ...and "LHS == (rhs1 & rhs2) i.e. "(rhs1 & rhs2)" is true
- then both rhs1 and rhs2 must be true. */
- tree rhs1 = gimple_assign_rhs1 (assign);
- tree rhs2 = gimple_assign_rhs2 (assign);
- add_constraint (rhs1, NE_EXPR, boolean_false_node, ctxt);
- add_constraint (rhs2, NE_EXPR, boolean_false_node, ctxt);
- }
- }
- break;
-
- case BIT_IOR_EXPR:
- {
- if (!is_true)
- {
- /* ...and "LHS == (rhs1 | rhs2)
- i.e. "(rhs1 | rhs2)" is false
- then both rhs1 and rhs2 must be false. */
- tree rhs1 = gimple_assign_rhs1 (assign);
- tree rhs2 = gimple_assign_rhs2 (assign);
- add_constraint (rhs1, EQ_EXPR, boolean_false_node, ctxt);
- add_constraint (rhs2, EQ_EXPR, boolean_false_node, ctxt);
- }
- }
- break;
-
- case EQ_EXPR:
- case NE_EXPR:
- {
- /* ...and "LHS == (rhs1 OP rhs2)"
- then rhs1 OP rhs2 must have the same logical value as LHS. */
- tree rhs1 = gimple_assign_rhs1 (assign);
- tree rhs2 = gimple_assign_rhs2 (assign);
- if (!is_true)
- rhs_code
- = invert_tree_comparison (rhs_code, false /* honor_nans */);
- add_constraint (rhs1, rhs_code, rhs2, ctxt);
- }
- break;
- }
-}
-
-/* Add any constraints for an SSA_NAME defined by CALL
- where the result OP RHS. */
-
-void
-region_model::add_any_constraints_from_gcall (enum tree_code op,
- tree rhs,
- const gcall *call,
- region_model_context *ctxt)
-{
- if (gimple_call_builtin_p (call, BUILT_IN_EXPECT)
- || gimple_call_builtin_p (call, BUILT_IN_EXPECT_WITH_PROBABILITY)
- || gimple_call_internal_p (call, IFN_BUILTIN_EXPECT))
- {
- /* __builtin_expect's return value is its initial argument. */
- add_constraint (gimple_call_arg (call, 0), op, rhs, ctxt);
- }
-}
-
/* Determine what is known about the condition "LHS OP RHS" within
this model.
Use CTXT for reporting any diagnostics associated with the accesses. */
@@ -2711,6 +2694,9 @@ region_model::get_representative_path_var_1 (const region *reg,
parent_pv.m_stack_depth);
}
+ case RK_SIZED:
+ return path_var (NULL_TREE, 0);
+
case RK_CAST:
{
path_var parent_pv
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index a4b584d..cf5232d 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -212,6 +212,8 @@ public:
virtual void visit_unaryop_svalue (const unaryop_svalue *) {}
virtual void visit_binop_svalue (const binop_svalue *) {}
virtual void visit_sub_svalue (const sub_svalue *) {}
+ virtual void visit_repeated_svalue (const repeated_svalue *) {}
+ virtual void visit_bits_within_svalue (const bits_within_svalue *) {}
virtual void visit_unmergeable_svalue (const unmergeable_svalue *) {}
virtual void visit_placeholder_svalue (const placeholder_svalue *) {}
virtual void visit_widening_svalue (const widening_svalue *) {}
@@ -255,6 +257,12 @@ public:
const svalue *get_or_create_sub_svalue (tree type,
const svalue *parent_svalue,
const region *subregion);
+ const svalue *get_or_create_repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue);
+ const svalue *get_or_create_bits_within (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue);
const svalue *get_or_create_unmergeable (const svalue *arg);
const svalue *get_or_create_widening_svalue (tree type,
const program_point &point,
@@ -286,6 +294,9 @@ public:
const region *get_offset_region (const region *parent,
tree type,
const svalue *byte_offset);
+ const region *get_sized_region (const region *parent,
+ tree type,
+ const svalue *byte_size_sval);
const region *get_cast_region (const region *original_region,
tree type);
const frame_region *get_frame_region (const frame_region *calling_frame,
@@ -321,6 +332,12 @@ private:
const svalue *maybe_fold_sub_svalue (tree type,
const svalue *parent_svalue,
const region *subregion);
+ const svalue *maybe_fold_repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue);
+ const svalue *maybe_fold_bits_within_svalue (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue);
const svalue *maybe_undo_optimize_bit_field_compare (tree type,
const compound_svalue *compound_sval,
tree cst, const svalue *arg1);
@@ -362,6 +379,14 @@ private:
typedef hash_map<sub_svalue::key_t, sub_svalue *> sub_values_map_t;
sub_values_map_t m_sub_values_map;
+ typedef hash_map<repeated_svalue::key_t,
+ repeated_svalue *> repeated_values_map_t;
+ repeated_values_map_t m_repeated_values_map;
+
+ typedef hash_map<bits_within_svalue::key_t,
+ bits_within_svalue *> bits_within_values_map_t;
+ bits_within_values_map_t m_bits_within_values_map;
+
typedef hash_map<const svalue *,
unmergeable_svalue *> unmergeable_values_map_t;
unmergeable_values_map_t m_unmergeable_values_map;
@@ -402,6 +427,7 @@ private:
consolidation_map<field_region> m_field_regions;
consolidation_map<element_region> m_element_regions;
consolidation_map<offset_region> m_offset_regions;
+ consolidation_map<sized_region> m_sized_regions;
consolidation_map<cast_region> m_cast_regions;
consolidation_map<frame_region> m_frame_regions;
consolidation_map<symbolic_region> m_symbolic_regions;
@@ -575,6 +601,7 @@ class region_model
void set_value (tree lhs, tree rhs, region_model_context *ctxt);
void clobber_region (const region *reg);
void purge_region (const region *reg);
+ void fill_region (const region *reg, const svalue *sval);
void zero_fill_region (const region *reg);
void mark_region_as_unknown (const region *reg, uncertainty_t *uncertainty);
@@ -664,18 +691,15 @@ class region_model
get_representative_path_var_1 (const region *reg,
svalue_set *visited) const;
- void add_any_constraints_from_ssa_def_stmt (tree lhs,
- enum tree_code op,
- tree rhs,
- region_model_context *ctxt);
- void add_any_constraints_from_gassign (enum tree_code op,
- tree rhs,
- const gassign *assign,
- region_model_context *ctxt);
- void add_any_constraints_from_gcall (enum tree_code op,
- tree rhs,
- const gcall *call,
- region_model_context *ctxt);
+ bool add_constraint (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs,
+ region_model_context *ctxt);
+ bool add_constraints_from_binop (const svalue *outer_lhs,
+ enum tree_code outer_op,
+ const svalue *outer_rhs,
+ bool *out,
+ region_model_context *ctxt);
void update_for_call_superedge (const call_superedge &call_edge,
region_model_context *ctxt);
@@ -754,7 +778,9 @@ class region_model_context
and use them to trigger sm-state transitions (e.g. transitions due
to ptrs becoming known to be NULL or non-NULL, rather than just
"unchecked") */
- virtual void on_condition (tree lhs, enum tree_code op, tree rhs) = 0;
+ virtual void on_condition (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs) = 0;
/* Hooks for clients to be notified when an unknown change happens
to SVAL (in response to a call to an unknown function). */
@@ -785,9 +811,9 @@ public:
void on_liveness_change (const svalue_set &,
const region_model *) OVERRIDE {}
logger *get_logger () OVERRIDE { return NULL; }
- void on_condition (tree lhs ATTRIBUTE_UNUSED,
+ void on_condition (const svalue *lhs ATTRIBUTE_UNUSED,
enum tree_code op ATTRIBUTE_UNUSED,
- tree rhs ATTRIBUTE_UNUSED) OVERRIDE
+ const svalue *rhs ATTRIBUTE_UNUSED) OVERRIDE
{
}
void on_unknown_change (const svalue *sval ATTRIBUTE_UNUSED,
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 5f246df..4633717 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -98,6 +98,7 @@ region::get_base_region () const
case RK_FIELD:
case RK_ELEMENT:
case RK_OFFSET:
+ case RK_SIZED:
iter = iter->get_parent_region ();
continue;
case RK_CAST:
@@ -121,6 +122,7 @@ region::base_region_p () const
case RK_FIELD:
case RK_ELEMENT:
case RK_OFFSET:
+ case RK_SIZED:
case RK_CAST:
return false;
@@ -188,7 +190,8 @@ region::get_offset () const
return *m_cached_offset;
}
-/* If the size of this region (in bytes) is known statically, write it to *OUT
+/* Base class implementation of region::get_byte_size vfunc.
+ If the size of this region (in bytes) is known statically, write it to *OUT
and return true.
Otherwise return false. */
@@ -208,8 +211,29 @@ region::get_byte_size (byte_size_t *out) const
return true;
}
-/* If the size of TYPE (in bits) is constant, write it to *OUT
- and return true.
+/* Base implementation of region::get_byte_size_sval vfunc. */
+
+const svalue *
+region::get_byte_size_sval (region_model_manager *mgr) const
+{
+ tree type = get_type ();
+
+ /* Bail out e.g. for heap-allocated regions. */
+ if (!type)
+ return mgr->get_or_create_unknown_svalue (size_type_node);
+
+ HOST_WIDE_INT bytes = int_size_in_bytes (type);
+ if (bytes == -1)
+ return mgr->get_or_create_unknown_svalue (size_type_node);
+
+ tree byte_size = size_in_bytes (type);
+ if (TREE_TYPE (byte_size) != size_type_node)
+ byte_size = fold_build1 (NOP_EXPR, size_type_node, byte_size);
+ return mgr->get_or_create_constant_svalue (byte_size);
+}
+
+/* Attempt to get the size of TYPE in bits.
+ If successful, return true and write the size to *OUT.
Otherwise return false. */
bool
@@ -249,7 +273,7 @@ region::get_bit_size (bit_size_t *out) const
/* Get the field within RECORD_TYPE at BIT_OFFSET. */
-static tree
+tree
get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset)
{
gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
@@ -375,18 +399,10 @@ region::calc_offset () const
= (const field_region *)iter_region;
iter_region = iter_region->get_parent_region ();
- /* Compare with e.g. gimple-fold.c's
- fold_nonarray_ctor_reference. */
- tree field = field_reg->get_field ();
- tree byte_offset = DECL_FIELD_OFFSET (field);
- if (TREE_CODE (byte_offset) != INTEGER_CST)
+ bit_offset_t rel_bit_offset;
+ if (!field_reg->get_relative_concrete_offset (&rel_bit_offset))
return region_offset::make_symbolic (iter_region);
- tree field_offset = DECL_FIELD_BIT_OFFSET (field);
- /* Compute bit offset of the field. */
- offset_int bitoffset
- = (wi::to_offset (field_offset)
- + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
- accum_bit_offset += bitoffset;
+ accum_bit_offset += rel_bit_offset;
}
continue;
@@ -396,28 +412,10 @@ region::calc_offset () const
= (const element_region *)iter_region;
iter_region = iter_region->get_parent_region ();
- if (tree idx_cst
- = element_reg->get_index ()->maybe_get_constant ())
- {
- gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
-
- tree elem_type = element_reg->get_type ();
- offset_int element_idx = wi::to_offset (idx_cst);
-
- /* First, use int_size_in_bytes, to reject the case where we
- have an incomplete type, or a non-constant value. */
- HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
- if (hwi_byte_size > 0)
- {
- offset_int element_bit_size
- = hwi_byte_size << LOG2_BITS_PER_UNIT;
- offset_int element_bit_offset
- = element_idx * element_bit_size;
- accum_bit_offset += element_bit_offset;
- continue;
- }
- }
- return region_offset::make_symbolic (iter_region);
+ bit_offset_t rel_bit_offset;
+ if (!element_reg->get_relative_concrete_offset (&rel_bit_offset))
+ return region_offset::make_symbolic (iter_region);
+ accum_bit_offset += rel_bit_offset;
}
continue;
@@ -427,22 +425,17 @@ region::calc_offset () const
= (const offset_region *)iter_region;
iter_region = iter_region->get_parent_region ();
- if (tree byte_offset_cst
- = offset_reg->get_byte_offset ()->maybe_get_constant ())
- {
- gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
- /* Use a signed value for the byte offset, to handle
- negative offsets. */
- HOST_WIDE_INT byte_offset
- = wi::to_offset (byte_offset_cst).to_shwi ();
- HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
- accum_bit_offset += bit_offset;
- }
- else
+ bit_offset_t rel_bit_offset;
+ if (!offset_reg->get_relative_concrete_offset (&rel_bit_offset))
return region_offset::make_symbolic (iter_region);
+ accum_bit_offset += rel_bit_offset;
}
continue;
+ case RK_SIZED:
+ iter_region = iter_region->get_parent_region ();
+ continue;
+
case RK_CAST:
{
const cast_region *cast_reg
@@ -458,6 +451,14 @@ region::calc_offset () const
return region_offset::make_concrete (iter_region, accum_bit_offset);
}
+/* Base implementation of region::get_relative_concrete_offset vfunc. */
+
+bool
+region::get_relative_concrete_offset (bit_offset_t *) const
+{
+ return false;
+}
+
/* Copy from SRC_REG to DST_REG, using CTXT for any issues that occur. */
void
@@ -984,7 +985,7 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
which can fail if we have a region with unknown size
(e.g. "extern const char arr[];"). */
const binding_key *binding
- = binding_key::make (mgr->get_store_manager (), this, BK_direct);
+ = binding_key::make (mgr->get_store_manager (), this);
if (binding->symbolic_p ())
return NULL;
@@ -1030,6 +1031,26 @@ field_region::dump_to_pp (pretty_printer *pp, bool simple) const
}
}
+/* Implementation of region::get_relative_concrete_offset vfunc
+ for field_region. */
+
+bool
+field_region::get_relative_concrete_offset (bit_offset_t *out) const
+{
+ /* Compare with e.g. gimple-fold.c's
+ fold_nonarray_ctor_reference. */
+ tree byte_offset = DECL_FIELD_OFFSET (m_field);
+ if (TREE_CODE (byte_offset) != INTEGER_CST)
+ return false;
+ tree field_offset = DECL_FIELD_BIT_OFFSET (m_field);
+ /* Compute bit offset of the field. */
+ offset_int bitoffset
+ = (wi::to_offset (field_offset)
+ + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
+ *out = bitoffset;
+ return true;
+}
+
/* class element_region : public region. */
/* Implementation of region::accept vfunc for element_region. */
@@ -1067,6 +1088,35 @@ element_region::dump_to_pp (pretty_printer *pp, bool simple) const
}
}
+/* Implementation of region::get_relative_concrete_offset vfunc
+ for element_region. */
+
+bool
+element_region::get_relative_concrete_offset (bit_offset_t *out) const
+{
+ if (tree idx_cst = m_index->maybe_get_constant ())
+ {
+ gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
+
+ tree elem_type = get_type ();
+ offset_int element_idx = wi::to_offset (idx_cst);
+
+ /* First, use int_size_in_bytes, to reject the case where we
+ have an incomplete type, or a non-constant value. */
+ HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
+ if (hwi_byte_size > 0)
+ {
+ offset_int element_bit_size
+ = hwi_byte_size << LOG2_BITS_PER_UNIT;
+ offset_int element_bit_offset
+ = element_idx * element_bit_size;
+ *out = element_bit_offset;
+ return true;
+ }
+ }
+ return false;
+}
+
/* class offset_region : public region. */
/* Implementation of region::accept vfunc for offset_region. */
@@ -1103,6 +1153,86 @@ offset_region::dump_to_pp (pretty_printer *pp, bool simple) const
}
}
+/* Implementation of region::get_relative_concrete_offset vfunc
+ for offset_region. */
+
+bool
+offset_region::get_relative_concrete_offset (bit_offset_t *out) const
+{
+ if (tree byte_offset_cst = m_byte_offset->maybe_get_constant ())
+ {
+ gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
+ /* Use a signed value for the byte offset, to handle
+ negative offsets. */
+ HOST_WIDE_INT byte_offset
+ = wi::to_offset (byte_offset_cst).to_shwi ();
+ HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
+ *out = bit_offset;
+ return true;
+ }
+ return false;
+}
+
+/* class sized_region : public region. */
+
+/* Implementation of region::accept vfunc for sized_region. */
+
+void
+sized_region::accept (visitor *v) const
+{
+ region::accept (v);
+ m_byte_size_sval->accept (v);
+}
+
+/* Implementation of region::dump_to_pp vfunc for sized_region. */
+
+void
+sized_region::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ if (simple)
+ {
+ pp_string (pp, "SIZED_REG(");
+ get_parent_region ()->dump_to_pp (pp, simple);
+ pp_string (pp, ", ");
+ m_byte_size_sval->dump_to_pp (pp, simple);
+ pp_string (pp, ")");
+ }
+ else
+ {
+ pp_string (pp, "sized_region(");
+ get_parent_region ()->dump_to_pp (pp, simple);
+ pp_string (pp, ", ");
+ m_byte_size_sval->dump_to_pp (pp, simple);
+ pp_printf (pp, ")");
+ }
+}
+
+/* Implementation of region::get_byte_size vfunc for sized_region. */
+
+bool
+sized_region::get_byte_size (byte_size_t *out) const
+{
+ if (tree cst = m_byte_size_sval->maybe_get_constant ())
+ {
+ gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+ *out = tree_to_uhwi (cst);
+ return true;
+ }
+ return false;
+}
+
+/* Implementation of region::get_bit_size vfunc for sized_region. */
+
+bool
+sized_region::get_bit_size (bit_size_t *out) const
+{
+ byte_size_t byte_size;
+ if (!get_byte_size (&byte_size))
+ return false;
+ *out = byte_size * BITS_PER_UNIT;
+ return true;
+}
+
/* class cast_region : public region. */
/* Implementation of region::accept vfunc for cast_region. */
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index 175a82a..353d5c4 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -43,6 +43,7 @@ enum region_kind
RK_FIELD,
RK_ELEMENT,
RK_OFFSET,
+ RK_SIZED,
RK_CAST,
RK_HEAP_ALLOCATED,
RK_ALLOCA,
@@ -70,6 +71,7 @@ enum region_kind
field_region (RK_FIELD)
element_region (RK_ELEMENT)
offset_region (RK_OFFSET)
+ sized_region (RK_SIZED)
cast_region (RK_CAST)
heap_allocated_region (RK_HEAP_ALLOCATED)
alloca_region (RK_ALLOCA)
@@ -107,6 +109,8 @@ public:
dyn_cast_element_region () const { return NULL; }
virtual const offset_region *
dyn_cast_offset_region () const { return NULL; }
+ virtual const sized_region *
+ dyn_cast_sized_region () const { return NULL; }
virtual const cast_region *
dyn_cast_cast_region () const { return NULL; }
virtual const string_region *
@@ -138,8 +142,25 @@ public:
static int cmp_ptr_ptr (const void *, const void *);
region_offset get_offset () const;
- bool get_byte_size (byte_size_t *out) const;
- bool get_bit_size (bit_size_t *out) const;
+
+ /* Attempt to get the size of this region as a concrete number of bytes.
+ If successful, return true and write the size to *OUT.
+ Otherwise return false. */
+ virtual bool get_byte_size (byte_size_t *out) const;
+
+ /* Attempt to get the size of this region as a concrete number of bits.
+ If successful, return true and write the size to *OUT.
+ Otherwise return false. */
+ virtual bool get_bit_size (bit_size_t *out) const;
+
+ /* Get a symbolic value describing the size of this region in bytes
+ (which could be "unknown"). */
+ virtual const svalue *get_byte_size_sval (region_model_manager *mgr) const;
+
+ /* Attempt to get the offset in bits of this region relative to its parent.
+ If successful, return true and write to *OUT.
+ Otherwise return false. */
+ virtual bool get_relative_concrete_offset (bit_offset_t *out) const;
void
get_subregions_for_binding (region_model_manager *mgr,
@@ -670,6 +691,8 @@ public:
tree get_field () const { return m_field; }
+ bool get_relative_concrete_offset (bit_offset_t *out) const FINAL OVERRIDE;
+
private:
tree m_field;
};
@@ -751,6 +774,9 @@ public:
const svalue *get_index () const { return m_index; }
+ virtual bool
+ get_relative_concrete_offset (bit_offset_t *out) const FINAL OVERRIDE;
+
private:
const svalue *m_index;
};
@@ -833,6 +859,8 @@ public:
const svalue *get_byte_offset () const { return m_byte_offset; }
+ bool get_relative_concrete_offset (bit_offset_t *out) const FINAL OVERRIDE;
+
private:
const svalue *m_byte_offset;
};
@@ -855,6 +883,99 @@ template <> struct default_hash_traits<offset_region::key_t>
namespace ana {
+/* A region that is size BYTES_SIZE_SVAL in size within its parent
+ region (or possibly larger, which would lead to an overflow. */
+
+class sized_region : public region
+{
+public:
+ /* A support class for uniquifying instances of sized_region. */
+ struct key_t
+ {
+ key_t (const region *parent, tree element_type,
+ const svalue *byte_size_sval)
+ : m_parent (parent), m_element_type (element_type),
+ m_byte_size_sval (byte_size_sval)
+ {
+ gcc_assert (byte_size_sval);
+ }
+
+ hashval_t hash () const
+ {
+ inchash::hash hstate;
+ hstate.add_ptr (m_parent);
+ hstate.add_ptr (m_element_type);
+ hstate.add_ptr (m_byte_size_sval);
+ return hstate.end ();
+ }
+
+ bool operator== (const key_t &other) const
+ {
+ return (m_parent == other.m_parent
+ && m_element_type == other.m_element_type
+ && m_byte_size_sval == other.m_byte_size_sval);
+ }
+
+ void mark_deleted () { m_byte_size_sval = reinterpret_cast<const svalue *> (1); }
+ void mark_empty () { m_byte_size_sval = NULL; }
+ bool is_deleted () const
+ {
+ return m_byte_size_sval == reinterpret_cast<const svalue *> (1);
+ }
+ bool is_empty () const { return m_byte_size_sval == NULL; }
+
+ const region *m_parent;
+ tree m_element_type;
+ const svalue *m_byte_size_sval;
+ const svalue *m_end_offset;
+ };
+
+ sized_region (unsigned id, const region *parent, tree type,
+ const svalue *byte_size_sval)
+ : region (complexity::from_pair (parent, byte_size_sval),
+ id, parent, type),
+ m_byte_size_sval (byte_size_sval)
+ {}
+
+ enum region_kind get_kind () const FINAL OVERRIDE { return RK_SIZED; }
+ const sized_region *
+ dyn_cast_sized_region () const FINAL OVERRIDE { return this; }
+
+ void accept (visitor *v) const FINAL OVERRIDE;
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+
+ bool get_byte_size (byte_size_t *out) const FINAL OVERRIDE;
+ bool get_bit_size (bit_size_t *out) const FINAL OVERRIDE;
+
+ const svalue *
+ get_byte_size_sval (region_model_manager *) const FINAL OVERRIDE
+ {
+ return m_byte_size_sval;
+ }
+
+private:
+ const svalue *m_byte_size_sval;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const sized_region *>::test (const region *reg)
+{
+ return reg->get_kind () == RK_SIZED;
+}
+
+template <> struct default_hash_traits<sized_region::key_t>
+: public member_function_hash_traits<sized_region::key_t>
+{
+ static const bool empty_zero_p = true;
+};
+
+namespace ana {
+
/* A region that views another region using a different type. */
class cast_region : public region
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 3a5f95d..b40a9a1 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -77,9 +77,9 @@ public:
void on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const FINAL OVERRIDE;
+ const svalue *rhs) const FINAL OVERRIDE;
bool can_purge_p (state_t s) const FINAL OVERRIDE;
pending_diagnostic *on_leak (tree var) const FINAL OVERRIDE;
@@ -381,19 +381,18 @@ void
fileptr_state_machine::on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const
+ const svalue *rhs) const
{
- if (!zerop (rhs))
+ if (!rhs->all_zeroes_p ())
return;
// TODO: has to be a FILE *, specifically
- if (TREE_CODE (TREE_TYPE (lhs)) != POINTER_TYPE)
+ if (!any_pointer_p (lhs))
return;
-
// TODO: has to be a FILE *, specifically
- if (TREE_CODE (TREE_TYPE (rhs)) != POINTER_TYPE)
+ if (!any_pointer_p (rhs))
return;
if (op == NE_EXPR)
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index a1582ca..40e64b3 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -375,9 +375,9 @@ public:
void on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const FINAL OVERRIDE;
+ const svalue *rhs) const FINAL OVERRIDE;
bool can_purge_p (state_t s) const FINAL OVERRIDE;
pending_diagnostic *on_leak (tree var) const FINAL OVERRIDE;
@@ -1863,11 +1863,11 @@ void
malloc_state_machine::on_condition (sm_context *sm_ctxt,
const supernode *node ATTRIBUTE_UNUSED,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const
+ const svalue *rhs) const
{
- if (!zerop (rhs))
+ if (!rhs->all_zeroes_p ())
return;
if (!any_pointer_p (lhs))
diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc
index 43b8475..4e28549 100644
--- a/gcc/analyzer/sm-pattern-test.cc
+++ b/gcc/analyzer/sm-pattern-test.cc
@@ -37,6 +37,12 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
#include "analyzer/pending-diagnostic.h"
+#include "tristate.h"
+#include "selftest.h"
+#include "analyzer/call-string.h"
+#include "analyzer/program-point.h"
+#include "analyzer/store.h"
+#include "analyzer/region-model.h"
#if ENABLE_ANALYZER
@@ -61,9 +67,9 @@ public:
void on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const FINAL OVERRIDE;
+ const svalue *rhs) const FINAL OVERRIDE;
bool can_purge_p (state_t s) const FINAL OVERRIDE;
};
@@ -118,18 +124,22 @@ void
pattern_test_state_machine::on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const
+ const svalue *rhs) const
{
if (stmt == NULL)
return;
- if (!CONSTANT_CLASS_P (rhs))
+ tree rhs_cst = rhs->maybe_get_constant ();
+ if (!rhs_cst)
return;
- pending_diagnostic *diag = new pattern_match (lhs, op, rhs);
- sm_ctxt->warn (node, stmt, lhs, diag);
+ if (tree lhs_expr = sm_ctxt->get_diagnostic_tree (lhs))
+ {
+ pending_diagnostic *diag = new pattern_match (lhs_expr, op, rhs_cst);
+ sm_ctxt->warn (node, stmt, lhs_expr, diag);
+ }
}
bool
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index 9703f7e..4add55e 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -58,13 +58,6 @@ public:
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;
/* State for "sensitive" data, such as a password. */
@@ -222,17 +215,6 @@ sensitive_state_machine::on_stmt (sm_context *sm_ctxt,
return false;
}
-void
-sensitive_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
sensitive_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
{
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index 42be809..fcbf322 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -81,13 +81,6 @@ public:
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;
/* These states are "global", rather than per-expression. */
@@ -363,20 +356,6 @@ signal_state_machine::on_stmt (sm_context *sm_ctxt,
return false;
}
-/* Implementation of state_machine::on_condition vfunc for
- signal_state_machine. */
-
-void
-signal_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
signal_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
{
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index e2460f9..721d3ea 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -61,9 +61,9 @@ public:
void on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs) const FINAL OVERRIDE;
+ const svalue *rhs) const FINAL OVERRIDE;
bool can_purge_p (state_t s) const FINAL OVERRIDE;
@@ -281,9 +281,9 @@ void
taint_state_machine::on_condition (sm_context *sm_ctxt,
const supernode *node,
const gimple *stmt,
- tree lhs,
+ const svalue *lhs,
enum tree_code op,
- tree rhs ATTRIBUTE_UNUSED) const
+ const svalue *rhs ATTRIBUTE_UNUSED) const
{
if (stmt == NULL)
return;
diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc
index 2d227dd..db07bf3 100644
--- a/gcc/analyzer/sm.cc
+++ b/gcc/analyzer/sm.cc
@@ -35,6 +35,11 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
+#include "tristate.h"
+#include "analyzer/call-string.h"
+#include "analyzer/program-point.h"
+#include "analyzer/store.h"
+#include "analyzer/svalue.h"
#if ENABLE_ANALYZER
@@ -48,6 +53,15 @@ any_pointer_p (tree var)
return POINTER_TYPE_P (TREE_TYPE (var));
}
+/* Return true if SVAL has pointer or reference type. */
+
+bool
+any_pointer_p (const svalue *sval)
+{
+ if (!sval->get_type ())
+ return false;
+ return POINTER_TYPE_P (sval->get_type ());
+}
/* class state_machine::state. */
diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h
index 8d4d030..6bb036e 100644
--- a/gcc/analyzer/sm.h
+++ b/gcc/analyzer/sm.h
@@ -29,7 +29,8 @@ class state_machine;
class sm_context;
class pending_diagnostic;
-extern bool any_pointer_p (tree var);
+extern bool any_pointer_p (tree expr);
+extern bool any_pointer_p (const svalue *sval);
/* An abstract base class for a state machine describing an API.
Manages a set of state objects, and has various virtual functions
@@ -89,10 +90,14 @@ public:
{
}
- virtual void on_condition (sm_context *sm_ctxt,
- const supernode *node,
- const gimple *stmt,
- tree lhs, enum tree_code op, tree rhs) const = 0;
+ virtual void on_condition (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ const supernode *node ATTRIBUTE_UNUSED,
+ const gimple *stmt ATTRIBUTE_UNUSED,
+ const svalue *lhs ATTRIBUTE_UNUSED,
+ enum tree_code op ATTRIBUTE_UNUSED,
+ const svalue *rhs ATTRIBUTE_UNUSED) const
+ {
+ }
/* Return true if it safe to discard the given state (to help
when simplifying state objects).
@@ -182,6 +187,8 @@ public:
/* Get the old state of VAR at STMT. */
virtual state_machine::state_t get_state (const gimple *stmt,
tree var) = 0;
+ virtual state_machine::state_t get_state (const gimple *stmt,
+ const svalue *) = 0;
/* Set the next state of VAR to be TO, recording the "origin" of the
state as ORIGIN.
Use STMT for location information. */
@@ -189,6 +196,10 @@ public:
tree var,
state_machine::state_t to,
tree origin = NULL_TREE) = 0;
+ virtual void set_next_state (const gimple *stmt,
+ const svalue *var,
+ state_machine::state_t to,
+ tree origin = NULL_TREE) = 0;
/* Called by state_machine in response to pattern matches:
if VAR is in state FROM, transition it to state TO, potentially
@@ -206,6 +217,18 @@ public:
set_next_state (stmt, var, to, origin);
}
+ void on_transition (const supernode *node ATTRIBUTE_UNUSED,
+ const gimple *stmt,
+ const svalue *var,
+ state_machine::state_t from,
+ state_machine::state_t to,
+ tree origin = NULL_TREE)
+ {
+ state_machine::state_t current = get_state (stmt, var);
+ if (current == from)
+ set_next_state (stmt, var, to, origin);
+ }
+
/* Called by state_machine in response to pattern matches:
issue a diagnostic D using NODE and STMT for location information. */
virtual void warn (const supernode *node, const gimple *stmt,
@@ -220,6 +243,7 @@ public:
{
return expr;
}
+ virtual tree get_diagnostic_tree (const svalue *) = 0;
virtual state_machine::state_t get_global_state () const = 0;
virtual void set_global_state (state_machine::state_t) = 0;
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index d5f8798..a65c741 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -118,52 +118,25 @@ uncertainty_t::dump (bool simple) const
pp_flush (&pp);
}
-/* Get a human-readable string for KIND for dumps. */
-
-const char *binding_kind_to_string (enum binding_kind kind)
-{
- switch (kind)
- {
- default:
- case BK_empty:
- case BK_deleted:
- /* We shouldn't be attempting to print the hash kinds. */
- gcc_unreachable ();
- case BK_direct:
- return "direct";
- case BK_default:
- return "default";
- }
-}
-
/* class binding_key. */
const binding_key *
-binding_key::make (store_manager *mgr, const region *r,
- enum binding_kind kind)
+binding_key::make (store_manager *mgr, const region *r)
{
region_offset offset = r->get_offset ();
if (offset.symbolic_p ())
- return mgr->get_symbolic_binding (r, kind);
+ return mgr->get_symbolic_binding (r);
else
{
bit_size_t bit_size;
if (r->get_bit_size (&bit_size))
return mgr->get_concrete_binding (offset.get_bit_offset (),
- bit_size, kind);
+ bit_size);
else
- return mgr->get_symbolic_binding (r, kind);
+ return mgr->get_symbolic_binding (r);
}
}
-/* Base class implementation of binding_key::dump_to_pp vfunc. */
-
-void
-binding_key::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
-{
- pp_printf (pp, "kind: %s", binding_kind_to_string (m_kind));
-}
-
/* Dump this binding_key to stderr. */
DEBUG_FUNCTION void
@@ -204,11 +177,6 @@ binding_key::cmp_ptrs (const void *p1, const void *p2)
int
binding_key::cmp (const binding_key *k1, const binding_key *k2)
{
- enum binding_kind kind1 = k1->get_kind ();
- enum binding_kind kind2 = k2->get_kind ();
- if (kind1 != kind2)
- return (int)kind1 - (int)kind2;
-
int concrete1 = k1->concrete_p ();
int concrete2 = k2->concrete_p ();
if (int concrete_cmp = concrete1 - concrete2)
@@ -236,7 +204,7 @@ binding_key::cmp (const binding_key *k1, const binding_key *k2)
}
}
-/* struct struct bit_range. */
+/* struct bit_range. */
void
bit_range::dump_to_pp (pretty_printer *pp) const
@@ -267,6 +235,24 @@ bit_range::dump () const
pp_flush (&pp);
}
+/* If OTHER is a subset of this, return true and write
+ to *OUT the relative range of OTHER within this.
+ Otherwise return false. */
+
+bool
+bit_range::contains_p (const bit_range &other, bit_range *out) const
+{
+ if (contains_p (other.get_start_bit_offset ())
+ && contains_p (other.get_last_bit_offset ()))
+ {
+ out->m_start_bit_offset = other.m_start_bit_offset - m_start_bit_offset;
+ out->m_size_in_bits = other.m_size_in_bits;
+ return true;
+ }
+ else
+ return false;
+}
+
int
bit_range::cmp (const bit_range &br1, const bit_range &br2)
{
@@ -371,15 +357,57 @@ byte_range::dump_to_pp (pretty_printer *pp) const
}
}
+/* Dump this object to stderr. */
+
+DEBUG_FUNCTION void
+byte_range::dump () const
+{
+ pretty_printer pp;
+ pp.buffer->stream = stderr;
+ dump_to_pp (&pp);
+ pp_newline (&pp);
+ pp_flush (&pp);
+}
+
+/* If OTHER is a subset of this, return true and write
+ to *OUT the relative range of OTHER within this.
+ Otherwise return false. */
+
+bool
+byte_range::contains_p (const byte_range &other, byte_range *out) const
+{
+ if (contains_p (other.get_start_byte_offset ())
+ && contains_p (other.get_last_byte_offset ()))
+ {
+ out->m_start_byte_offset = other.m_start_byte_offset - m_start_byte_offset;
+ out->m_size_in_bytes = other.m_size_in_bytes;
+ return true;
+ }
+ else
+ return false;
+}
+
+/* qsort comparator for byte ranges. */
+
+int
+byte_range::cmp (const byte_range &br1, const byte_range &br2)
+{
+ /* Order first by offset. */
+ if (int start_cmp = wi::cmps (br1.m_start_byte_offset,
+ br2.m_start_byte_offset))
+ return start_cmp;
+
+ /* ...then by size. */
+ return wi::cmpu (br1.m_size_in_bytes, br2.m_size_in_bytes);
+}
+
/* class concrete_binding : public binding_key. */
/* Implementation of binding_key::dump_to_pp vfunc for concrete_binding. */
void
-concrete_binding::dump_to_pp (pretty_printer *pp, bool simple) const
+concrete_binding::dump_to_pp (pretty_printer *pp, bool) const
{
- binding_key::dump_to_pp (pp, simple);
- pp_string (pp, ", ");
m_bit_range.dump_to_pp (pp);
}
@@ -402,9 +430,6 @@ concrete_binding::cmp_ptr_ptr (const void *p1, const void *p2)
const concrete_binding *b1 = *(const concrete_binding * const *)p1;
const concrete_binding *b2 = *(const concrete_binding * const *)p2;
- if (int kind_cmp = b1->get_kind () - b2->get_kind ())
- return kind_cmp;
-
return bit_range::cmp (b1->m_bit_range, b2->m_bit_range);
}
@@ -413,8 +438,8 @@ concrete_binding::cmp_ptr_ptr (const void *p1, const void *p2)
void
symbolic_binding::dump_to_pp (pretty_printer *pp, bool simple) const
{
- binding_key::dump_to_pp (pp, simple);
- pp_string (pp, ", region: ");
+ //binding_key::dump_to_pp (pp, simple);
+ pp_string (pp, "region: ");
m_region->dump_to_pp (pp, simple);
}
@@ -426,9 +451,6 @@ symbolic_binding::cmp_ptr_ptr (const void *p1, const void *p2)
const symbolic_binding *b1 = *(const symbolic_binding * const *)p1;
const symbolic_binding *b2 = *(const symbolic_binding * const *)p2;
- if (int kind_cmp = b1->get_kind () - b2->get_kind ())
- return kind_cmp;
-
return region::cmp_ids (b1->get_region (), b2->get_region ());
}
@@ -777,8 +799,7 @@ binding_map::apply_ctor_val_to_range (const region *parent_reg,
return false;
bit_offset_t start_bit_offset = min_offset.get_bit_offset ();
store_manager *smgr = mgr->get_store_manager ();
- const binding_key *max_element_key
- = binding_key::make (smgr, max_element, BK_direct);
+ const binding_key *max_element_key = binding_key::make (smgr, max_element);
if (max_element_key->symbolic_p ())
return false;
const concrete_binding *max_element_ckey
@@ -786,8 +807,7 @@ binding_map::apply_ctor_val_to_range (const region *parent_reg,
bit_size_t range_size_in_bits
= max_element_ckey->get_next_bit_offset () - start_bit_offset;
const concrete_binding *range_key
- = smgr->get_concrete_binding (start_bit_offset, range_size_in_bits,
- BK_direct);
+ = smgr->get_concrete_binding (start_bit_offset, range_size_in_bits);
if (range_key->symbolic_p ())
return false;
@@ -819,8 +839,7 @@ binding_map::apply_ctor_pair_to_child_region (const region *parent_reg,
{
const svalue *sval = get_svalue_for_ctor_val (val, mgr);
const binding_key *k
- = binding_key::make (mgr->get_store_manager (), child_reg,
- BK_direct);
+ = binding_key::make (mgr->get_store_manager (), child_reg);
/* Handle the case where we have an unknown size for child_reg
(e.g. due to it being a trailing field with incomplete array
type. */
@@ -844,7 +863,7 @@ binding_map::apply_ctor_pair_to_child_region (const region *parent_reg,
- parent_base_offset.get_bit_offset ());
/* Create a concrete key for the child within the parent. */
k = mgr->get_store_manager ()->get_concrete_binding
- (child_parent_offset, sval_bit_size, BK_direct);
+ (child_parent_offset, sval_bit_size);
}
gcc_assert (k->concrete_p ());
put (k, sval);
@@ -852,6 +871,166 @@ binding_map::apply_ctor_pair_to_child_region (const region *parent_reg,
}
}
+/* Populate OUT with all bindings within this map that overlap KEY. */
+
+void
+binding_map::get_overlapping_bindings (const binding_key *key,
+ auto_vec<const binding_key *> *out)
+{
+ for (auto iter : *this)
+ {
+ const binding_key *iter_key = iter.first;
+ if (const concrete_binding *ckey
+ = key->dyn_cast_concrete_binding ())
+ {
+ if (const concrete_binding *iter_ckey
+ = iter_key->dyn_cast_concrete_binding ())
+ {
+ if (ckey->overlaps_p (*iter_ckey))
+ out->safe_push (iter_key);
+ }
+ else
+ {
+ /* Assume overlap. */
+ out->safe_push (iter_key);
+ }
+ }
+ else
+ {
+ /* Assume overlap. */
+ out->safe_push (iter_key);
+ }
+ }
+}
+
+/* Remove, truncate, and/or split any bindings within this map that
+ overlap DROP_KEY.
+
+ For example, if we have:
+
+ +------------------------------------+
+ | old binding |
+ +------------------------------------+
+
+ which is to be overwritten with:
+
+ .......+----------------------+.......
+ .......| new binding |.......
+ .......+----------------------+.......
+
+ this function "cuts a hole" out of the old binding:
+
+ +------+......................+------+
+ |prefix| hole for new binding |suffix|
+ +------+......................+------+
+
+ into which the new binding can be added without
+ overlapping the prefix or suffix.
+
+ The prefix and suffix (if added) will be bound to the pertinent
+ parts of the value of the old binding.
+
+ For example, given:
+ struct s5
+ {
+ char arr[8];
+ };
+ void test_5 (struct s5 *p)
+ {
+ struct s5 f = *p;
+ f.arr[3] = 42;
+ }
+ then after the "f = *p;" we have:
+ cluster for: f: INIT_VAL((*INIT_VAL(p_33(D))))
+ and at the "f.arr[3] = 42;" we remove the bindings overlapping
+ "f.arr[3]", replacing it with a prefix (bytes 0-2) and suffix (bytes 4-7)
+ giving:
+ cluster for: f
+ key: {bytes 0-2}
+ value: {BITS_WITHIN(bytes 0-2, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
+ key: {bytes 4-7}
+ value: {BITS_WITHIN(bytes 4-7, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
+ punching a hole into which the new value can be written at byte 3:
+ cluster for: f
+ key: {bytes 0-2}
+ value: {BITS_WITHIN(bytes 0-2, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
+ key: {byte 3}
+ value: 'char' {(char)42}
+ key: {bytes 4-7}
+ value: {BITS_WITHIN(bytes 4-7, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
+
+ If UNCERTAINTY is non-NULL, use it to record any svalues that
+ were removed, as being maybe-bound. */
+
+void
+binding_map::remove_overlapping_bindings (store_manager *mgr,
+ const binding_key *drop_key,
+ uncertainty_t *uncertainty)
+{
+ auto_vec<const binding_key *> bindings;
+ get_overlapping_bindings (drop_key, &bindings);
+
+ unsigned i;
+ const binding_key *iter_binding;
+ FOR_EACH_VEC_ELT (bindings, i, iter_binding)
+ {
+ const svalue *old_sval = get (iter_binding);
+ if (uncertainty)
+ uncertainty->on_maybe_bound_sval (old_sval);
+
+ /* Begin by removing the old binding. */
+ m_map.remove (iter_binding);
+
+ /* Now potentially add the prefix and suffix. */
+ if (const concrete_binding *drop_ckey
+ = drop_key->dyn_cast_concrete_binding ())
+ if (const concrete_binding *iter_ckey
+ = iter_binding->dyn_cast_concrete_binding ())
+ {
+ gcc_assert (drop_ckey->overlaps_p (*iter_ckey));
+
+ const bit_range &drop_bits = drop_ckey->get_bit_range ();
+ const bit_range &iter_bits = iter_ckey->get_bit_range ();
+
+ if (iter_bits.get_start_bit_offset ()
+ < drop_bits.get_start_bit_offset ())
+ {
+ /* We have a truncated prefix. */
+ bit_range prefix_bits (iter_bits.get_start_bit_offset (),
+ (drop_bits.get_start_bit_offset ()
+ - iter_bits.get_start_bit_offset ()));
+ const concrete_binding *prefix_key
+ = mgr->get_concrete_binding (prefix_bits);
+ bit_range rel_prefix (0, prefix_bits.m_size_in_bits);
+ const svalue *prefix_sval
+ = old_sval->extract_bit_range (NULL_TREE,
+ rel_prefix,
+ mgr->get_svalue_manager ());
+ m_map.put (prefix_key, prefix_sval);
+ }
+
+ if (iter_bits.get_next_bit_offset ()
+ > drop_bits.get_next_bit_offset ())
+ {
+ /* We have a truncated suffix. */
+ bit_range suffix_bits (drop_bits.get_next_bit_offset (),
+ (iter_bits.get_next_bit_offset ()
+ - drop_bits.get_next_bit_offset ()));
+ const concrete_binding *suffix_key
+ = mgr->get_concrete_binding (suffix_bits);
+ bit_range rel_suffix (drop_bits.get_next_bit_offset ()
+ - iter_bits.get_start_bit_offset (),
+ suffix_bits.m_size_in_bits);
+ const svalue *suffix_sval
+ = old_sval->extract_bit_range (NULL_TREE,
+ rel_suffix,
+ mgr->get_svalue_manager ());
+ m_map.put (suffix_key, suffix_sval);
+ }
+ }
+ }
+}
+
/* class binding_cluster. */
/* binding_cluster's copy ctor. */
@@ -964,6 +1143,27 @@ binding_cluster::dump (bool simple) const
pp_flush (&pp);
}
+/* Assert that this object is valid. */
+
+void
+binding_cluster::validate () const
+{
+ int num_symbolic = 0;
+ int num_concrete = 0;
+ for (auto iter : m_map)
+ {
+ if (iter.first->symbolic_p ())
+ num_symbolic++;
+ else
+ num_concrete++;
+ }
+ /* We shouldn't have more than one symbolic key per cluster
+ (or one would have clobbered the other). */
+ gcc_assert (num_symbolic < 2);
+ /* We can't have both concrete and symbolic keys. */
+ gcc_assert (num_concrete == 0 || num_symbolic == 0);
+}
+
/* Return a new json::object of the form
{"escaped": true/false,
"touched": true/false,
@@ -986,8 +1186,7 @@ binding_cluster::to_json () const
void
binding_cluster::bind (store_manager *mgr,
- const region *reg, const svalue *sval,
- binding_kind kind)
+ const region *reg, const svalue *sval)
{
if (const compound_svalue *compound_sval
= sval->dyn_cast_compound_svalue ())
@@ -996,7 +1195,7 @@ binding_cluster::bind (store_manager *mgr,
return;
}
- const binding_key *binding = binding_key::make (mgr, reg, kind);
+ const binding_key *binding = binding_key::make (mgr, reg);
bind_key (binding, sval);
}
@@ -1045,8 +1244,7 @@ binding_cluster::bind_compound_sval (store_manager *mgr,
+ reg_offset.get_bit_offset ());
const concrete_binding *effective_concrete_key
= mgr->get_concrete_binding (effective_start,
- concrete_key->get_size_in_bits (),
- iter_key->get_kind ());
+ concrete_key->get_size_in_bits ());
bind_key (effective_concrete_key, iter_sval);
}
else
@@ -1069,31 +1267,35 @@ binding_cluster::purge_region (store_manager *mgr, const region *reg)
{
gcc_assert (reg->get_kind () == RK_DECL);
const binding_key *binding
- = binding_key::make (mgr, const_cast<region *> (reg),
- BK_direct);
+ = binding_key::make (mgr, const_cast<region *> (reg));
m_map.remove (binding);
}
-/* Mark REG within this cluster as being filled with zeroes.
- Remove all bindings, add a default binding to zero, and clear the
- TOUCHED flag. */
+/* Clobber REG and fill it with repeated copies of SVAL. */
void
-binding_cluster::zero_fill_region (store_manager *mgr, const region *reg)
+binding_cluster::fill_region (store_manager *mgr,
+ const region *reg,
+ const svalue *sval)
{
clobber_region (mgr, reg);
- /* Add a default binding to zero. */
region_model_manager *sval_mgr = mgr->get_svalue_manager ();
- const svalue *cst_sval
- = sval_mgr->get_or_create_int_cst (integer_type_node, 0);
- const svalue *bound_sval = cst_sval;
- if (reg->get_type ())
- bound_sval = sval_mgr->get_or_create_unaryop (reg->get_type (), NOP_EXPR,
- cst_sval);
- bind (mgr, reg, bound_sval, BK_default);
+ const svalue *byte_size_sval = reg->get_byte_size_sval (sval_mgr);
+ const svalue *fill_sval
+ = sval_mgr->get_or_create_repeated_svalue (reg->get_type (),
+ byte_size_sval, sval);
+ bind (mgr, reg, fill_sval);
+}
+
+/* Clobber REG within this cluster and fill it with zeroes. */
- m_touched = false;
+void
+binding_cluster::zero_fill_region (store_manager *mgr, const region *reg)
+{
+ region_model_manager *sval_mgr = mgr->get_svalue_manager ();
+ const svalue *zero_sval = sval_mgr->get_or_create_int_cst (char_type_node, 0);
+ fill_region (mgr, reg, zero_sval);
}
/* Mark REG within this cluster as being unknown.
@@ -1111,7 +1313,7 @@ binding_cluster::mark_region_as_unknown (store_manager *mgr,
region_model_manager *sval_mgr = mgr->get_svalue_manager ();
const svalue *sval
= sval_mgr->get_or_create_unknown_svalue (reg->get_type ());
- bind (mgr, reg, sval, BK_default);
+ bind (mgr, reg, sval);
}
/* Get any SVAL bound to REG within this cluster via kind KIND,
@@ -1119,10 +1321,9 @@ binding_cluster::mark_region_as_unknown (store_manager *mgr,
const svalue *
binding_cluster::get_binding (store_manager *mgr,
- const region *reg,
- binding_kind kind) const
+ const region *reg) const
{
- const binding_key *reg_binding = binding_key::make (mgr, reg, kind);
+ const binding_key *reg_binding = binding_key::make (mgr, reg);
const svalue *sval = m_map.get (reg_binding);
if (sval)
{
@@ -1140,7 +1341,7 @@ binding_cluster::get_binding (store_manager *mgr,
while (const region *parent_reg = reg->get_parent_region ())
{
const binding_key *parent_reg_binding
- = binding_key::make (mgr, parent_reg, kind);
+ = binding_key::make (mgr, parent_reg);
if (parent_reg_binding == reg_binding
&& sval->get_type ()
&& reg->get_type ()
@@ -1161,7 +1362,7 @@ binding_cluster::get_binding (store_manager *mgr,
FOR_EACH_VEC_ELT_REVERSE (regions, i, iter_reg)
{
region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
- sval = rmm_mgr->get_or_create_sub_svalue (reg->get_type (),
+ sval = rmm_mgr->get_or_create_sub_svalue (iter_reg->get_type (),
sval, iter_reg);
}
}
@@ -1169,21 +1370,20 @@ binding_cluster::get_binding (store_manager *mgr,
return sval;
}
-/* Get any SVAL bound to REG within this cluster via kind KIND,
+/* Get any SVAL bound to REG within this cluster,
either directly for REG, or recursively checking for bindings within
parent regions and extracting subvalues if need be. */
const svalue *
binding_cluster::get_binding_recursive (store_manager *mgr,
- const region *reg,
- enum binding_kind kind) const
+ const region *reg) const
{
- if (const svalue *sval = get_binding (mgr, reg, kind))
+ if (const svalue *sval = get_binding (mgr, reg))
return sval;
if (reg != m_base_region)
if (const region *parent_reg = reg->get_parent_region ())
if (const svalue *parent_sval
- = get_binding_recursive (mgr, parent_reg, kind))
+ = get_binding_recursive (mgr, parent_reg))
{
/* Extract child svalue from parent svalue. */
region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
@@ -1199,18 +1399,11 @@ const svalue *
binding_cluster::get_any_binding (store_manager *mgr,
const region *reg) const
{
- /* Look for a "direct" binding. */
+ /* Look for a direct binding. */
if (const svalue *direct_sval
- = get_binding_recursive (mgr, reg, BK_direct))
+ = get_binding_recursive (mgr, reg))
return direct_sval;
- /* Look for a "default" binding, but not if there's been a symbolic
- write. */
- if (!m_touched)
- if (const svalue *default_sval
- = get_binding_recursive (mgr, reg, BK_default))
- return default_sval;
-
/* If this cluster has been touched by a symbolic write, then the content
of any subregion not currently specifically bound is "UNKNOWN". */
if (m_touched)
@@ -1251,8 +1444,6 @@ const svalue *
binding_cluster::maybe_get_compound_binding (store_manager *mgr,
const region *reg) const
{
- binding_map map;
-
region_offset cluster_offset = m_base_region->get_offset ();
if (cluster_offset.symbolic_p ())
return NULL;
@@ -1260,6 +1451,36 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr,
if (reg_offset.symbolic_p ())
return NULL;
+ region_model_manager *sval_mgr = mgr->get_svalue_manager ();
+
+ /* We will a build the result map in two parts:
+ (a) result_map, holding the concrete keys from this cluster,
+
+ (b) default_map, holding the initial values for the region
+ (e.g. uninitialized, initializer values, or zero), unless this
+ cluster has been touched.
+
+ We will populate (a), and as we do, clobber (b), trimming and
+ splitting its bindings as necessary.
+ Finally, we will merge (b) into (a), giving a concrete map
+ that merges both the initial values and the bound values from
+ the binding_cluster.
+ Doing it this way reduces N for the O(N^2) intersection-finding,
+ perhaps we should have a spatial-organized data structure for
+ concrete keys, though. */
+
+ binding_map result_map;
+ binding_map default_map;
+
+ /* Set up default values in default_map. */
+ const svalue *default_sval;
+ if (m_touched)
+ default_sval = sval_mgr->get_or_create_unknown_svalue (reg->get_type ());
+ else
+ default_sval = sval_mgr->get_or_create_initial_value (reg);
+ const binding_key *default_key = binding_key::make (mgr, reg);
+ default_map.put (default_key, default_sval);
+
for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
{
const binding_key *key = (*iter).first;
@@ -1268,78 +1489,77 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr,
if (const concrete_binding *concrete_key
= key->dyn_cast_concrete_binding ())
{
- /* Skip bindings that are outside the bit range of REG. */
- if (concrete_key->get_start_bit_offset ()
- < reg_offset.get_bit_offset ())
- continue;
- bit_size_t reg_bit_size;
- if (reg->get_bit_size (&reg_bit_size))
- if (concrete_key->get_start_bit_offset ()
- >= reg_offset.get_bit_offset () + reg_bit_size)
- continue;
-
- /* Get offset of KEY relative to REG, rather than to
- the cluster. */
- bit_offset_t relative_start
- = (concrete_key->get_start_bit_offset ()
- - reg_offset.get_bit_offset ());
- const concrete_binding *offset_concrete_key
- = mgr->get_concrete_binding (relative_start,
- concrete_key->get_size_in_bits (),
- key->get_kind ());
- map.put (offset_concrete_key, sval);
- }
- else
- return NULL;
- }
+ const bit_range &bound_range = concrete_key->get_bit_range ();
- if (map.elements () == 0)
- return NULL;
+ bit_size_t reg_bit_size;
+ if (!reg->get_bit_size (&reg_bit_size))
+ return NULL;
- region_model_manager *sval_mgr = mgr->get_svalue_manager ();
- return sval_mgr->get_or_create_compound_svalue (reg->get_type (), map);
-}
+ bit_range reg_range (reg_offset.get_bit_offset (),
+ reg_bit_size);
+ /* Skip bindings that are outside the bit range of REG. */
+ if (!bound_range.intersects_p (reg_range))
+ continue;
-/* Populate OUT with all bindings within this cluster that overlap REG. */
+ /* We shouldn't have an exact match; that should have been
+ handled already. */
+ gcc_assert (!(reg_range == bound_range));
-void
-binding_cluster::get_overlapping_bindings (store_manager *mgr,
- const region *reg,
- auto_vec<const binding_key *> *out)
-{
- const binding_key *binding
- = binding_key::make (mgr, reg, BK_direct);
- for (map_t::iterator iter = m_map.begin ();
- iter != m_map.end (); ++iter)
- {
- const binding_key *iter_key = (*iter).first;
- if (const concrete_binding *ckey
- = binding->dyn_cast_concrete_binding ())
- {
- if (const concrete_binding *iter_ckey
- = iter_key->dyn_cast_concrete_binding ())
+ bit_range subrange (0, 0);
+ if (reg_range.contains_p (bound_range, &subrange))
{
- if (ckey->overlaps_p (*iter_ckey))
- out->safe_push (iter_key);
+ /* We have a bound range fully within REG.
+ Add it to map, offsetting accordingly. */
+
+ /* Get offset of KEY relative to REG, rather than to
+ the cluster. */
+ const concrete_binding *offset_concrete_key
+ = mgr->get_concrete_binding (subrange);
+ result_map.put (offset_concrete_key, sval);
+
+ /* Clobber default_map, removing/trimming/spliting where
+ it overlaps with offset_concrete_key. */
+ default_map.remove_overlapping_bindings (mgr,
+ offset_concrete_key,
+ NULL);
+ }
+ else if (bound_range.contains_p (reg_range, &subrange))
+ {
+ /* REG is fully within the bound range, but
+ is not equal to it; we're extracting a subvalue. */
+ return sval->extract_bit_range (reg->get_type (),
+ subrange,
+ mgr->get_svalue_manager ());
}
else
{
- /* Assume overlap. */
- out->safe_push (iter_key);
+ /* REG and the bound range partially overlap.
+ We don't handle this case yet. */
+ return NULL;
}
}
else
- {
- /* Assume overlap. */
- out->safe_push (iter_key);
- }
+ /* Can't handle symbolic bindings. */
+ return NULL;
+ }
+
+ if (result_map.elements () == 0)
+ return NULL;
+
+ /* Merge any bindings from default_map into result_map. */
+ for (auto iter : default_map)
+ {
+ const binding_key *key = iter.first;
+ const svalue *sval = iter.second;
+ result_map.put (key, sval);
}
+
+ return sval_mgr->get_or_create_compound_svalue (reg->get_type (), result_map);
}
-/* Remove any bindings within this cluster that overlap REG,
- but retain default bindings that overlap but aren't fully covered
- by REG.
+/* Remove, truncate, and/or split any bindings within this map that
+ overlap REG.
If UNCERTAINTY is non-NULL, use it to record any svalues that
were removed, as being maybe-bound. */
@@ -1348,26 +1568,9 @@ binding_cluster::remove_overlapping_bindings (store_manager *mgr,
const region *reg,
uncertainty_t *uncertainty)
{
- auto_vec<const binding_key *> bindings;
- get_overlapping_bindings (mgr, reg, &bindings);
+ const binding_key *reg_binding = binding_key::make (mgr, reg);
- unsigned i;
- const binding_key *iter_binding;
- FOR_EACH_VEC_ELT (bindings, i, iter_binding)
- {
- /* Don't remove default bindings, unless the default binding
- is fully covered by REG. */
- if (iter_binding->get_kind () == BK_default)
- {
- const binding_key *reg_binding
- = binding_key::make (mgr, reg, BK_default);
- if (reg_binding != iter_binding)
- continue;
- }
- if (uncertainty)
- uncertainty->on_maybe_bound_sval (m_map.get (iter_binding));
- m_map.remove (iter_binding);
- }
+ m_map.remove_overlapping_bindings (mgr, reg_binding, uncertainty);
}
/* Attempt to merge CLUSTER_A and CLUSTER_B into OUT_CLUSTER, using
@@ -1428,6 +1631,8 @@ binding_cluster::can_merge_p (const binding_cluster *cluster_a,
const binding_key *key_b = (*iter_b).first;
keys.add (key_b);
}
+ int num_symbolic_keys = 0;
+ int num_concrete_keys = 0;
for (hash_set<const binding_key *>::iterator iter = keys.begin ();
iter != keys.end (); ++iter)
{
@@ -1435,6 +1640,11 @@ binding_cluster::can_merge_p (const binding_cluster *cluster_a,
const svalue *sval_a = cluster_a->get_any_value (key);
const svalue *sval_b = cluster_b->get_any_value (key);
+ if (key->symbolic_p ())
+ num_symbolic_keys++;
+ else
+ num_concrete_keys++;
+
if (sval_a == sval_b)
{
gcc_assert (sval_a);
@@ -1463,29 +1673,15 @@ binding_cluster::can_merge_p (const binding_cluster *cluster_a,
out_cluster->m_map.put (key, unknown_sval);
}
- /* Handle the case where we get a default binding from one and a direct
- binding from the other. */
- auto_vec<const concrete_binding *> duplicate_keys;
- for (map_t::iterator iter = out_cluster->m_map.begin ();
- iter != out_cluster->m_map.end (); ++iter)
- {
- const concrete_binding *ckey
- = (*iter).first->dyn_cast_concrete_binding ();
- if (!ckey)
- continue;
- if (ckey->get_kind () != BK_direct)
- continue;
- const concrete_binding *def_ckey
- = mgr->get_concrete_binding (ckey->get_start_bit_offset (),
- ckey->get_size_in_bits (),
- BK_default);
- if (out_cluster->m_map.get (def_ckey))
- duplicate_keys.safe_push (def_ckey);
+ /* We can only have at most one symbolic key per cluster,
+ and if we do, we can't have any concrete keys.
+ If this happens, mark the cluster as touched, with no keys. */
+ if (num_symbolic_keys >= 2
+ || (num_concrete_keys > 0 && num_symbolic_keys > 0))
+ {
+ out_cluster->m_touched = true;
+ out_cluster->m_map.empty ();
}
- unsigned i;
- const concrete_binding *key;
- FOR_EACH_VEC_ELT (duplicate_keys, i, key)
- out_cluster->m_map.remove (key);
/* We don't handle other kinds of overlaps yet. */
@@ -1558,7 +1754,7 @@ binding_cluster::on_unknown_fncall (const gcall *call,
const svalue *sval
= mgr->get_svalue_manager ()->get_or_create_conjured_svalue
(m_base_region->get_type (), call, m_base_region);
- bind (mgr, m_base_region, sval, BK_direct);
+ bind (mgr, m_base_region, sval);
m_touched = true;
}
@@ -1665,7 +1861,7 @@ binding_cluster::maybe_get_simple_value (store_manager *mgr) const
if (m_map.elements () != 1)
return NULL;
- const binding_key *key = binding_key::make (mgr, m_base_region, BK_direct);
+ const binding_key *key = binding_key::make (mgr, m_base_region);
return get_any_value (key);
}
@@ -1675,10 +1871,9 @@ binding_cluster::maybe_get_simple_value (store_manager *mgr) const
const concrete_binding *
store_manager::get_concrete_binding (bit_offset_t start_bit_offset,
- bit_offset_t size_in_bits,
- enum binding_kind kind)
+ bit_offset_t size_in_bits)
{
- concrete_binding b (start_bit_offset, size_in_bits, kind);
+ concrete_binding b (start_bit_offset, size_in_bits);
if (concrete_binding *existing = m_concrete_binding_key_mgr.get (b))
return existing;
@@ -1688,10 +1883,9 @@ store_manager::get_concrete_binding (bit_offset_t start_bit_offset,
}
const symbolic_binding *
-store_manager::get_symbolic_binding (const region *reg,
- enum binding_kind kind)
+store_manager::get_symbolic_binding (const region *reg)
{
- symbolic_binding b (reg, kind);
+ symbolic_binding b (reg);
if (symbolic_binding *existing = m_symbolic_binding_key_mgr.get (b))
return existing;
@@ -1952,6 +2146,15 @@ store::dump (bool simple) const
pp_flush (&pp);
}
+/* Assert that this object is valid. */
+
+void
+store::validate () const
+{
+ for (auto iter : m_cluster_map)
+ iter.second->validate ();
+}
+
/* Return a new json::object of the form
{PARENT_REGION_DESC: {BASE_REGION_DESC: object for binding_map,
... for each cluster within parent region},
@@ -2027,7 +2230,7 @@ store::get_any_binding (store_manager *mgr, const region *reg) const
void
store::set_value (store_manager *mgr, const region *lhs_reg,
- const svalue *rhs_sval, enum binding_kind kind,
+ const svalue *rhs_sval,
uncertainty_t *uncertainty)
{
remove_overlapping_bindings (mgr, lhs_reg);
@@ -2054,7 +2257,7 @@ store::set_value (store_manager *mgr, const region *lhs_reg,
else
{
lhs_cluster = get_or_create_cluster (lhs_base_reg);
- lhs_cluster->bind (mgr, lhs_reg, rhs_sval, kind);
+ lhs_cluster->bind (mgr, lhs_reg, rhs_sval);
}
/* Bindings to a cluster can affect other clusters if a symbolic
@@ -2209,16 +2412,26 @@ store::purge_region (store_manager *mgr, const region *reg)
}
}
-/* Zero-fill REG. */
+/* Fill REG with SVAL. */
void
-store::zero_fill_region (store_manager *mgr, const region *reg)
+store::fill_region (store_manager *mgr, const region *reg, const svalue *sval)
{
const region *base_reg = reg->get_base_region ();
if (base_reg->symbolic_for_unknown_ptr_p ())
return;
binding_cluster *cluster = get_or_create_cluster (base_reg);
- cluster->zero_fill_region (mgr, reg);
+ cluster->fill_region (mgr, reg, sval);
+}
+
+/* Zero-fill REG. */
+
+void
+store::zero_fill_region (store_manager *mgr, const region *reg)
+{
+ region_model_manager *sval_mgr = mgr->get_svalue_manager ();
+ const svalue *zero_sval = sval_mgr->get_or_create_int_cst (char_type_node, 0);
+ fill_region (mgr, reg, zero_sval);
}
/* Mark REG as having unknown content. */
@@ -2740,26 +2953,18 @@ test_binding_key_overlap ()
store_manager mgr (NULL);
/* Various 8-bit bindings. */
- const concrete_binding *cb_0_7
- = mgr.get_concrete_binding (0, 8, BK_direct);
- const concrete_binding *cb_8_15
- = mgr.get_concrete_binding (8, 8, BK_direct);
- const concrete_binding *cb_16_23
- = mgr.get_concrete_binding (16, 8, BK_direct);
- const concrete_binding *cb_24_31
- = mgr.get_concrete_binding (24, 8, BK_direct);
+ const concrete_binding *cb_0_7 = mgr.get_concrete_binding (0, 8);
+ const concrete_binding *cb_8_15 = mgr.get_concrete_binding (8, 8);
+ const concrete_binding *cb_16_23 = mgr.get_concrete_binding (16, 8);
+ const concrete_binding *cb_24_31 = mgr.get_concrete_binding (24, 8);
/* 16-bit bindings. */
- const concrete_binding *cb_0_15
- = mgr.get_concrete_binding (0, 16, BK_direct);
- const concrete_binding *cb_8_23
- = mgr.get_concrete_binding (8, 16, BK_direct);
- const concrete_binding *cb_16_31
- = mgr.get_concrete_binding (16, 16, BK_direct);
+ const concrete_binding *cb_0_15 = mgr.get_concrete_binding (0, 16);
+ const concrete_binding *cb_8_23 = mgr.get_concrete_binding (8, 16);
+ const concrete_binding *cb_16_31 = mgr.get_concrete_binding (16, 16);
/* 32-bit binding. */
- const concrete_binding *cb_0_31
- = mgr.get_concrete_binding (0, 32, BK_direct);
+ const concrete_binding *cb_0_31 = mgr.get_concrete_binding (0, 32);
/* Everything should self-overlap. */
ASSERT_OVERLAP (cb_0_7, cb_0_7);
diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h
index e0c60e1..2ac2923 100644
--- a/gcc/analyzer/store.h
+++ b/gcc/analyzer/store.h
@@ -199,29 +199,6 @@ private:
class byte_range;
class concrete_binding;
-/* An enum for discriminating between "direct" vs "default" levels of
- mapping. */
-
-enum binding_kind
-{
- /* Special-case value for hash support.
- This is the initial entry, so that hash traits can have
- empty_zero_p = true. */
- BK_empty = 0,
-
- /* Special-case value for hash support. */
- BK_deleted,
-
- /* The normal kind of mapping. */
- BK_direct,
-
- /* A lower-priority kind of mapping, for use when inheriting
- default values from a parent region. */
- BK_default
-};
-
-extern const char *binding_kind_to_string (enum binding_kind kind);
-
/* Abstract base class for describing ranges of bits within a binding_map
that can have svalues bound to them. */
@@ -232,10 +209,9 @@ public:
virtual bool concrete_p () const = 0;
bool symbolic_p () const { return !concrete_p (); }
- static const binding_key *make (store_manager *mgr, const region *r,
- enum binding_kind kind);
+ static const binding_key *make (store_manager *mgr, const region *r);
- virtual void dump_to_pp (pretty_printer *pp, bool simple) const;
+ virtual void dump_to_pp (pretty_printer *pp, bool simple) const = 0;
void dump (bool simple) const;
label_text get_desc (bool simple=true) const;
@@ -244,28 +220,6 @@ public:
virtual const concrete_binding *dyn_cast_concrete_binding () const
{ return NULL; }
-
- enum binding_kind get_kind () const { return m_kind; }
-
- void mark_deleted () { m_kind = BK_deleted; }
- void mark_empty () { m_kind = BK_empty; }
- bool is_deleted () const { return m_kind == BK_deleted; }
- bool is_empty () const { return m_kind == BK_empty; }
-
-protected:
- binding_key (enum binding_kind kind) : m_kind (kind) {}
-
- hashval_t impl_hash () const
- {
- return m_kind;
- }
- bool impl_eq (const binding_key &other) const
- {
- return m_kind == other.m_kind;
- }
-
-private:
- enum binding_kind m_kind;
};
/* A concrete range of bits. */
@@ -288,6 +242,10 @@ struct bit_range
{
return m_start_bit_offset + m_size_in_bits;
}
+ bit_offset_t get_last_bit_offset () const
+ {
+ return get_next_bit_offset () - 1;
+ }
bool contains_p (bit_offset_t offset) const
{
@@ -295,6 +253,8 @@ struct bit_range
&& offset < get_next_bit_offset ());
}
+ bool contains_p (const bit_range &other, bit_range *out) const;
+
bool operator== (const bit_range &other) const
{
return (m_start_bit_offset == other.m_start_bit_offset
@@ -327,12 +287,42 @@ struct byte_range
{}
void dump_to_pp (pretty_printer *pp) const;
+ void dump () const;
+
+ bool contains_p (byte_offset_t offset) const
+ {
+ return (offset >= get_start_byte_offset ()
+ && offset < get_next_byte_offset ());
+ }
+ bool contains_p (const byte_range &other, byte_range *out) const;
+
+ bool operator== (const byte_range &other) const
+ {
+ return (m_start_byte_offset == other.m_start_byte_offset
+ && m_size_in_bytes == other.m_size_in_bytes);
+ }
+ byte_offset_t get_start_byte_offset () const
+ {
+ return m_start_byte_offset;
+ }
+ byte_offset_t get_next_byte_offset () const
+ {
+ return m_start_byte_offset + m_size_in_bytes;
+ }
byte_offset_t get_last_byte_offset () const
{
return m_start_byte_offset + m_size_in_bytes - 1;
}
+ bit_range as_bit_range () const
+ {
+ return bit_range (m_start_byte_offset * BITS_PER_UNIT,
+ m_size_in_bytes * BITS_PER_UNIT);
+ }
+
+ static int cmp (const byte_range &br1, const byte_range &br2);
+
byte_offset_t m_start_byte_offset;
byte_size_t m_size_in_bytes;
};
@@ -346,10 +336,8 @@ public:
/* This class is its own key for the purposes of consolidation. */
typedef concrete_binding key_t;
- concrete_binding (bit_offset_t start_bit_offset, bit_size_t size_in_bits,
- enum binding_kind kind)
- : binding_key (kind),
- m_bit_range (start_bit_offset, size_in_bits)
+ concrete_binding (bit_offset_t start_bit_offset, bit_size_t size_in_bits)
+ : m_bit_range (start_bit_offset, size_in_bits)
{}
bool concrete_p () const FINAL OVERRIDE { return true; }
@@ -358,12 +346,10 @@ public:
inchash::hash hstate;
hstate.add_wide_int (m_bit_range.m_start_bit_offset);
hstate.add_wide_int (m_bit_range.m_size_in_bits);
- return hstate.end () ^ binding_key::impl_hash ();
+ return hstate.end ();
}
bool operator== (const concrete_binding &other) const
{
- if (!binding_key::impl_eq (other))
- return false;
return m_bit_range == other.m_bit_range;
}
@@ -392,6 +378,11 @@ public:
static int cmp_ptr_ptr (const void *, const void *);
+ void mark_deleted () { m_bit_range.m_start_bit_offset = -1; }
+ void mark_empty () { m_bit_range.m_start_bit_offset = -2; }
+ bool is_deleted () const { return m_bit_range.m_start_bit_offset == -1; }
+ bool is_empty () const { return m_bit_range.m_start_bit_offset == -2; }
+
private:
bit_range m_bit_range;
};
@@ -401,7 +392,7 @@ private:
template <> struct default_hash_traits<ana::concrete_binding>
: public member_function_hash_traits<ana::concrete_binding>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -415,21 +406,16 @@ public:
/* This class is its own key for the purposes of consolidation. */
typedef symbolic_binding key_t;
- symbolic_binding (const region *region, enum binding_kind kind)
- : binding_key (kind),
- m_region (region)
- {}
+ symbolic_binding (const region *region) : m_region (region) {}
bool concrete_p () const FINAL OVERRIDE { return false; }
hashval_t hash () const
{
- return (binding_key::impl_hash () ^ (intptr_t)m_region);
+ return (intptr_t)m_region;
}
bool operator== (const symbolic_binding &other) const
{
- if (!binding_key::impl_eq (other))
- return false;
- return (m_region == other.m_region);
+ return m_region == other.m_region;
}
void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
@@ -438,6 +424,12 @@ public:
static int cmp_ptr_ptr (const void *, const void *);
+ void mark_deleted () { m_region = reinterpret_cast<const region *> (1); }
+ void mark_empty () { m_region = NULL; }
+ bool is_deleted () const
+ { return m_region == reinterpret_cast<const region *> (1); }
+ bool is_empty () const { return m_region == NULL; }
+
private:
const region *m_region;
};
@@ -504,7 +496,13 @@ public:
static int cmp (const binding_map &map1, const binding_map &map2);
+ void remove_overlapping_bindings (store_manager *mgr,
+ const binding_key *drop_key,
+ uncertainty_t *uncertainty);
+
private:
+ void get_overlapping_bindings (const binding_key *key,
+ auto_vec<const binding_key *> *out);
bool apply_ctor_val_to_range (const region *parent_reg,
region_model_manager *mgr,
tree min_index, tree max_index,
@@ -553,22 +551,22 @@ public:
void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
void dump (bool simple) const;
+ void validate () const;
+
json::object *to_json () const;
- void bind (store_manager *mgr, const region *, const svalue *,
- binding_kind kind);
+ void bind (store_manager *mgr, const region *, const svalue *);
void clobber_region (store_manager *mgr, const region *reg);
void purge_region (store_manager *mgr, const region *reg);
+ void fill_region (store_manager *mgr, const region *reg, const svalue *sval);
void zero_fill_region (store_manager *mgr, const region *reg);
void mark_region_as_unknown (store_manager *mgr, const region *reg,
uncertainty_t *uncertainty);
- const svalue *get_binding (store_manager *mgr, const region *reg,
- binding_kind kind) const;
+ const svalue *get_binding (store_manager *mgr, const region *reg) const;
const svalue *get_binding_recursive (store_manager *mgr,
- const region *reg,
- enum binding_kind kind) const;
+ const region *reg) const;
const svalue *get_any_binding (store_manager *mgr,
const region *reg) const;
const svalue *maybe_get_compound_binding (store_manager *mgr,
@@ -630,8 +628,6 @@ public:
private:
const svalue *get_any_value (const binding_key *key) const;
- void get_overlapping_bindings (store_manager *mgr, const region *reg,
- auto_vec<const binding_key *> *out);
void bind_compound_sval (store_manager *mgr,
const region *reg,
const compound_svalue *compound_sval);
@@ -684,6 +680,8 @@ public:
void dump (bool simple) const;
void summarize_to_pp (pretty_printer *pp, bool simple) const;
+ void validate () const;
+
json::object *to_json () const;
const svalue *get_any_binding (store_manager *mgr, const region *reg) const;
@@ -691,10 +689,11 @@ public:
bool called_unknown_fn_p () const { return m_called_unknown_fn; }
void set_value (store_manager *mgr, const region *lhs_reg,
- const svalue *rhs_sval, enum binding_kind kind,
+ const svalue *rhs_sval,
uncertainty_t *uncertainty);
void clobber_region (store_manager *mgr, const region *reg);
void purge_region (store_manager *mgr, const region *reg);
+ void fill_region (store_manager *mgr, const region *reg, const svalue *sval);
void zero_fill_region (store_manager *mgr, const region *reg);
void mark_region_as_unknown (store_manager *mgr, const region *reg,
uncertainty_t *uncertainty);
@@ -773,19 +772,15 @@ public:
/* binding consolidation. */
const concrete_binding *
get_concrete_binding (bit_offset_t start_bit_offset,
- bit_offset_t size_in_bits,
- enum binding_kind kind);
+ bit_offset_t size_in_bits);
const concrete_binding *
- get_concrete_binding (const bit_range &bits,
- enum binding_kind kind)
+ get_concrete_binding (const bit_range &bits)
{
return get_concrete_binding (bits.get_start_bit_offset (),
- bits.m_size_in_bits,
- kind);
+ bits.m_size_in_bits);
}
const symbolic_binding *
- get_symbolic_binding (const region *region,
- enum binding_kind kind);
+ get_symbolic_binding (const region *region);
region_model_manager *get_svalue_manager () const
{
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index a16563d..70c23f0 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -415,6 +415,27 @@ svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
sub_sval2->get_subregion ());
}
break;
+ case SK_REPEATED:
+ {
+ const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
+ const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
+ return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
+ repeated_sval2->get_inner_svalue ());
+ }
+ break;
+ case SK_BITS_WITHIN:
+ {
+ const bits_within_svalue *bits_within_sval1
+ = (const bits_within_svalue *)sval1;
+ const bits_within_svalue *bits_within_sval2
+ = (const bits_within_svalue *)sval2;
+ if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
+ bits_within_sval2->get_bits ()))
+ return cmp;
+ return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
+ bits_within_sval2->get_inner_svalue ());
+ }
+ break;
case SK_UNMERGEABLE:
{
const unmergeable_svalue *unmergeable_sval1
@@ -515,6 +536,36 @@ svalue::involves_p (const svalue *other) const
return v.found_p ();
}
+/* Extract SUBRANGE from this value, of type TYPE. */
+
+const svalue *
+svalue::extract_bit_range (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const
+{
+ return mgr->get_or_create_bits_within (type, subrange, this);
+}
+
+/* Base implementation of svalue::maybe_fold_bits_within vfunc. */
+
+const svalue *
+svalue::maybe_fold_bits_within (tree,
+ const bit_range &,
+ region_model_manager *) const
+{
+ /* By default, don't fold. */
+ return NULL;
+}
+
+/* Base implementation of svalue::all_zeroes_p.
+ Return true if this value is known to be all zeroes. */
+
+bool
+svalue::all_zeroes_p () const
+{
+ return false;
+}
+
/* class region_svalue : public svalue. */
/* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
@@ -680,6 +731,34 @@ constant_svalue::eval_condition (const constant_svalue *lhs,
return tristate::TS_UNKNOWN;
}
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for constant_svalue. */
+
+const svalue *
+constant_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &,
+ region_model_manager *mgr) const
+{
+ /* Bits within an all-zero value are also all zero. */
+ if (zerop (m_cst_expr))
+ {
+ if (type)
+ return mgr->get_or_create_cast (type, this);
+ else
+ return this;
+ }
+ /* Otherwise, don't fold. */
+ return NULL;
+}
+
+/* Implementation of svalue::all_zeroes_p for constant_svalue. */
+
+bool
+constant_svalue::all_zeroes_p () const
+{
+ return zerop (m_cst_expr);
+}
+
/* class unknown_svalue : public svalue. */
/* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
@@ -711,6 +790,18 @@ unknown_svalue::accept (visitor *v) const
v->visit_unknown_svalue (this);
}
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for unknown_svalue. */
+
+const svalue *
+unknown_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &,
+ region_model_manager *mgr) const
+{
+ /* Bits within an unknown_svalue are themselves unknown. */
+ return mgr->get_or_create_unknown_svalue (type);
+}
+
/* Get a string for KIND for use in debug dumps. */
const char *
@@ -892,6 +983,34 @@ unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
return get_arg ()->live_p (live_svalues, model);
}
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for unaryop_svalue. */
+
+const svalue *
+unaryop_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &,
+ region_model_manager *mgr) const
+{
+ switch (m_op)
+ {
+ default:
+ break;
+ case NOP_EXPR:
+ /* A cast of zero is zero. */
+ if (tree cst = m_arg->maybe_get_constant ())
+ if (zerop (cst))
+ {
+ if (type)
+ return mgr->get_or_create_cast (type, this);
+ else
+ return this;
+ }
+ break;
+ }
+ /* Otherwise, don't fold. */
+ return NULL;
+}
+
/* class binop_svalue : public svalue. */
/* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
@@ -995,6 +1114,213 @@ sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
return get_parent ()->live_p (live_svalues, model);
}
+/* class repeated_svalue : public svalue. */
+
+/* repeated_svalue'c ctor. */
+
+repeated_svalue::repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue)
+: svalue (complexity::from_pair (outer_size, inner_svalue), type),
+ m_outer_size (outer_size),
+ m_inner_svalue (inner_svalue)
+{
+}
+
+/* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
+
+void
+repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ if (simple)
+ {
+ pp_string (pp, "REPEATED(");
+ if (get_type ())
+ {
+ print_quoted_type (pp, get_type ());
+ pp_string (pp, ", ");
+ }
+ pp_string (pp, "outer_size: ");
+ m_outer_size->dump_to_pp (pp, simple);
+ pp_string (pp, ", inner_val: ");
+ m_inner_svalue->dump_to_pp (pp, simple);
+ pp_character (pp, ')');
+ }
+ else
+ {
+ pp_string (pp, "repeated_svalue (");
+ if (get_type ())
+ {
+ print_quoted_type (pp, get_type ());
+ pp_string (pp, ", ");
+ }
+ pp_string (pp, "outer_size: ");
+ m_outer_size->dump_to_pp (pp, simple);
+ pp_string (pp, ", inner_val: ");
+ m_inner_svalue->dump_to_pp (pp, simple);
+ pp_character (pp, ')');
+ }
+}
+
+/* Implementation of svalue::accept vfunc for repeated_svalue. */
+
+void
+repeated_svalue::accept (visitor *v) const
+{
+ v->visit_repeated_svalue (this);
+ m_inner_svalue->accept (v);
+}
+
+/* Implementation of svalue::all_zeroes_p for repeated_svalue. */
+
+bool
+repeated_svalue::all_zeroes_p () const
+{
+ return m_inner_svalue->all_zeroes_p ();
+}
+
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for repeated_svalue. */
+
+const svalue *
+repeated_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &bits,
+ region_model_manager *mgr) const
+{
+ const svalue *innermost_sval = m_inner_svalue;
+ /* Fold
+ BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
+ to:
+ REPEATED_SVALUE (ZERO). */
+ if (all_zeroes_p ())
+ {
+ byte_range bytes (0,0);
+ if (bits.as_byte_range (&bytes))
+ {
+ const svalue *byte_size
+ = mgr->get_or_create_int_cst (size_type_node,
+ bytes.m_size_in_bytes.to_uhwi ());
+ return mgr->get_or_create_repeated_svalue (type, byte_size,
+ innermost_sval);
+ }
+ }
+
+ /* Fold:
+ BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
+ to:
+ BITS_WITHIN (range - offset, INNERMOST_SVALUE)
+ if range is fully within one instance of INNERMOST_SVALUE. */
+ if (tree innermost_type = innermost_sval->get_type ())
+ {
+ bit_size_t element_bit_size;
+ if (int_size_in_bits (innermost_type, &element_bit_size)
+ && element_bit_size > 0)
+ {
+ HOST_WIDE_INT start_idx
+ = (bits.get_start_bit_offset ()
+ / element_bit_size).to_shwi ();
+ HOST_WIDE_INT last_idx
+ = (bits.get_last_bit_offset ()
+ / element_bit_size).to_shwi ();
+ if (start_idx == last_idx)
+ {
+ bit_offset_t start_of_element
+ = start_idx * element_bit_size;
+ bit_range range_within_element
+ (bits.m_start_bit_offset - start_of_element,
+ bits.m_size_in_bits);
+ return mgr->get_or_create_bits_within (type,
+ range_within_element,
+ innermost_sval);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* class bits_within_svalue : public svalue. */
+
+/* bits_within_svalue'c ctor. */
+
+bits_within_svalue::bits_within_svalue (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue)
+: svalue (complexity (inner_svalue), type),
+ m_bits (bits),
+ m_inner_svalue (inner_svalue)
+{
+}
+
+/* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
+
+void
+bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ if (simple)
+ {
+ pp_string (pp, "BITS_WITHIN(");
+ if (get_type ())
+ {
+ print_quoted_type (pp, get_type ());
+ pp_string (pp, ", ");
+ }
+ m_bits.dump_to_pp (pp);
+ pp_string (pp, ", inner_val: ");
+ m_inner_svalue->dump_to_pp (pp, simple);
+ pp_character (pp, ')');
+ }
+ else
+ {
+ pp_string (pp, "bits_within_svalue (");
+ if (get_type ())
+ {
+ print_quoted_type (pp, get_type ());
+ pp_string (pp, ", ");
+ }
+ m_bits.dump_to_pp (pp);
+ pp_string (pp, ", inner_val: ");
+ m_inner_svalue->dump_to_pp (pp, simple);
+ pp_character (pp, ')');
+ }
+}
+
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for bits_within_svalue. */
+
+const svalue *
+bits_within_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &bits,
+ region_model_manager *mgr) const
+{
+ /* Fold:
+ BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
+ to:
+ BITS_WITHIN (range1 in range 2, VAL). */
+ bit_range offset_bits (m_bits.get_start_bit_offset ()
+ + bits.m_start_bit_offset,
+ bits.m_size_in_bits);
+ return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
+}
+
+/* Implementation of svalue::accept vfunc for bits_within_svalue. */
+
+void
+bits_within_svalue::accept (visitor *v) const
+{
+ v->visit_bits_within_svalue (this);
+ m_inner_svalue->accept (v);
+}
+
+/* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
+
+bool
+bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
+ const region_model *model) const
+{
+ return m_inner_svalue->live_p (live_svalues, model);
+}
+
/* class widening_svalue : public svalue. */
/* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
@@ -1291,6 +1617,75 @@ compound_svalue::calc_complexity (const binding_map &map)
return complexity (num_child_nodes + 1, max_child_depth + 1);
}
+/* Implementation of svalue::maybe_fold_bits_within vfunc
+ for compound_svalue. */
+
+const svalue *
+compound_svalue::maybe_fold_bits_within (tree type,
+ const bit_range &bits,
+ region_model_manager *mgr) const
+{
+ binding_map result_map;
+ for (auto iter : m_map)
+ {
+ const binding_key *key = iter.first;
+ if (const concrete_binding *conc_key
+ = key->dyn_cast_concrete_binding ())
+ {
+ /* Ignore concrete bindings outside BITS. */
+ if (!conc_key->get_bit_range ().intersects_p (bits))
+ continue;
+
+ const svalue *sval = iter.second;
+ /* Get the position of conc_key relative to BITS. */
+ bit_range result_location (conc_key->get_start_bit_offset ()
+ - bits.get_start_bit_offset (),
+ conc_key->get_size_in_bits ());
+ /* If conc_key starts after BITS, trim off leading bits
+ from the svalue and adjust binding location. */
+ if (result_location.m_start_bit_offset < 0)
+ {
+ bit_size_t leading_bits_to_drop
+ = -result_location.m_start_bit_offset;
+ result_location = bit_range
+ (0, result_location.m_size_in_bits - leading_bits_to_drop);
+ bit_range bits_within_sval (leading_bits_to_drop,
+ result_location.m_size_in_bits);
+ /* Trim off leading bits from iter_sval. */
+ sval = mgr->get_or_create_bits_within (NULL_TREE,
+ bits_within_sval,
+ sval);
+ }
+ /* If conc_key finishes after BITS, trim off trailing bits
+ from the svalue and adjust binding location. */
+ if (conc_key->get_next_bit_offset ()
+ > bits.get_next_bit_offset ())
+ {
+ bit_size_t trailing_bits_to_drop
+ = (conc_key->get_next_bit_offset ()
+ - bits.get_next_bit_offset ());
+ result_location = bit_range
+ (result_location.m_start_bit_offset,
+ result_location.m_size_in_bits - trailing_bits_to_drop);
+ bit_range bits_within_sval (0,
+ result_location.m_size_in_bits);
+ /* Trim off leading bits from iter_sval. */
+ sval = mgr->get_or_create_bits_within (NULL_TREE,
+ bits_within_sval,
+ sval);
+ }
+ const concrete_binding *offset_conc_key
+ = mgr->get_store_manager ()->get_concrete_binding
+ (result_location);
+ result_map.put (offset_conc_key, sval);
+ }
+ else
+ /* If we have any symbolic keys we can't get it as bits. */
+ return NULL;
+ }
+ return mgr->get_or_create_compound_svalue (type, result_map);
+}
+
/* class conjured_svalue : public svalue. */
/* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h
index d9e34aa..5552fcf 100644
--- a/gcc/analyzer/svalue.h
+++ b/gcc/analyzer/svalue.h
@@ -41,6 +41,8 @@ enum svalue_kind
SK_UNARYOP,
SK_BINOP,
SK_SUB,
+ SK_REPEATED,
+ SK_BITS_WITHIN,
SK_UNMERGEABLE,
SK_PLACEHOLDER,
SK_WIDENING,
@@ -63,6 +65,9 @@ enum svalue_kind
unaryop_svalue (SK_UNARYOP): unary operation on another svalue
binop_svalue (SK_BINOP): binary operation on two svalues
sub_svalue (SK_SUB): the result of accessing a subregion
+ repeated_svalue (SK_REPEATED): repeating an svalue to fill a larger region
+ bits_within_svalue (SK_BITS_WITHIN): a range of bits/bytes within a larger
+ svalue
unmergeable_svalue (SK_UNMERGEABLE): a value that is so interesting
from a control-flow perspective that it can inhibit state-merging
placeholder_svalue (SK_PLACEHOLDER): for use in selftests.
@@ -107,6 +112,10 @@ public:
dyn_cast_binop_svalue () const { return NULL; }
virtual const sub_svalue *
dyn_cast_sub_svalue () const { return NULL; }
+ virtual const repeated_svalue *
+ dyn_cast_repeated_svalue () const { return NULL; }
+ virtual const bits_within_svalue *
+ dyn_cast_bits_within_svalue () const { return NULL; }
virtual const unmergeable_svalue *
dyn_cast_unmergeable_svalue () const { return NULL; }
virtual const widening_svalue *
@@ -138,6 +147,18 @@ public:
bool involves_p (const svalue *other) const;
+ const svalue *
+ extract_bit_range (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const;
+
+ virtual const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const;
+
+ virtual bool all_zeroes_p () const;
+
protected:
svalue (complexity c, tree type)
: m_complexity (c), m_type (type)
@@ -175,9 +196,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
const region *m_reg;
@@ -222,7 +243,7 @@ is_a_helper <const region_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<region_svalue::key_t>
: public member_function_hash_traits<region_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -253,6 +274,13 @@ public:
enum tree_code op,
const constant_svalue *rhs);
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
+
+ bool all_zeroes_p () const FINAL OVERRIDE;
+
private:
tree m_cst_expr;
};
@@ -285,6 +313,11 @@ public:
void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
void accept (visitor *v) const FINAL OVERRIDE;
+
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
};
/* An enum describing a particular kind of "poisoned" value. */
@@ -327,9 +360,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
enum poison_kind m_kind;
tree m_type;
@@ -364,7 +397,7 @@ is_a_helper <const poisoned_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<poisoned_svalue::key_t>
: public member_function_hash_traits<poisoned_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -426,9 +459,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
setjmp_record m_record;
tree m_type;
@@ -467,7 +500,7 @@ is_a_helper <const setjmp_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<setjmp_svalue::key_t>
: public member_function_hash_traits<setjmp_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -548,9 +581,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
enum tree_code m_op;
@@ -574,6 +607,11 @@ public:
enum tree_code get_op () const { return m_op; }
const svalue *get_arg () const { return m_arg; }
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
+
private:
enum tree_code m_op;
const svalue *m_arg;
@@ -592,7 +630,7 @@ is_a_helper <const unaryop_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<unaryop_svalue::key_t>
: public member_function_hash_traits<unaryop_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -630,9 +668,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
enum tree_code m_op;
@@ -683,7 +721,7 @@ is_a_helper <const binop_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<binop_svalue::key_t>
: public member_function_hash_traits<binop_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -719,9 +757,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
const svalue *m_parent_svalue;
@@ -762,7 +800,182 @@ is_a_helper <const sub_svalue *>::test (const svalue *sval)
template <> struct default_hash_traits<sub_svalue::key_t>
: public member_function_hash_traits<sub_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
+};
+
+namespace ana {
+
+/* Concrete subclass of svalue representing repeating an inner svalue
+ (possibly not a whole number of times) to fill a larger region of
+ type TYPE of size OUTER_SIZE bytes. */
+
+class repeated_svalue : public svalue
+{
+public:
+ /* A support class for uniquifying instances of repeated_svalue. */
+ struct key_t
+ {
+ key_t (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue)
+ : m_type (type), m_outer_size (outer_size), m_inner_svalue (inner_svalue)
+ {}
+
+ hashval_t hash () const
+ {
+ inchash::hash hstate;
+ hstate.add_ptr (m_type);
+ hstate.add_ptr (m_outer_size);
+ hstate.add_ptr (m_inner_svalue);
+ return hstate.end ();
+ }
+
+ bool operator== (const key_t &other) const
+ {
+ return (m_type == other.m_type
+ && m_outer_size == other.m_outer_size
+ && m_inner_svalue == other.m_inner_svalue);
+ }
+
+ void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
+ bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
+
+ tree m_type;
+ const svalue *m_outer_size;
+ const svalue *m_inner_svalue;
+ };
+ repeated_svalue (tree type,
+ const svalue *outer_size,
+ const svalue *inner_svalue);
+
+ enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_REPEATED; }
+ const repeated_svalue *dyn_cast_repeated_svalue () const FINAL OVERRIDE
+ {
+ return this;
+ }
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+ void accept (visitor *v) const FINAL OVERRIDE;
+
+ const svalue *get_outer_size () const { return m_outer_size; }
+ const svalue *get_inner_svalue () const { return m_inner_svalue; }
+
+ bool all_zeroes_p () const FINAL OVERRIDE;
+
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
+
+ private:
+ const svalue *m_outer_size;
+ const svalue *m_inner_svalue;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const repeated_svalue *>::test (const svalue *sval)
+{
+ return sval->get_kind () == SK_REPEATED;
+}
+
+template <> struct default_hash_traits<repeated_svalue::key_t>
+: public member_function_hash_traits<repeated_svalue::key_t>
+{
+ static const bool empty_zero_p = false;
+};
+
+namespace ana {
+
+/* A range of bits/bytes within another svalue
+ e.g. bytes 5-39 of INITIAL_SVALUE(R).
+ These can be generated for prefixes and suffixes when part of a binding
+ is clobbered, so that we don't lose too much information. */
+
+class bits_within_svalue : public svalue
+{
+public:
+ /* A support class for uniquifying instances of bits_within_svalue. */
+ struct key_t
+ {
+ key_t (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue)
+ : m_type (type), m_bits (bits), m_inner_svalue (inner_svalue)
+ {}
+
+ hashval_t hash () const
+ {
+ inchash::hash hstate;
+ hstate.add_ptr (m_type);
+ hstate.add_ptr (m_inner_svalue);
+ return hstate.end ();
+ }
+
+ bool operator== (const key_t &other) const
+ {
+ return (m_type == other.m_type
+ && m_bits == other.m_bits
+ && m_inner_svalue == other.m_inner_svalue);
+ }
+
+ void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
+ bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
+
+ tree m_type;
+ bit_range m_bits;
+ const svalue *m_inner_svalue;
+ };
+ bits_within_svalue (tree type,
+ const bit_range &bits,
+ const svalue *inner_svalue);
+
+ enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_BITS_WITHIN; }
+ const bits_within_svalue *
+ dyn_cast_bits_within_svalue () const FINAL OVERRIDE
+ {
+ return this;
+ }
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+ void accept (visitor *v) const FINAL OVERRIDE;
+ bool implicitly_live_p (const svalue_set *,
+ const region_model *) const FINAL OVERRIDE;
+
+ const bit_range &get_bits () const { return m_bits; }
+ const svalue *get_inner_svalue () const { return m_inner_svalue; }
+
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
+
+ private:
+ const bit_range m_bits;
+ const svalue *m_inner_svalue;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const bits_within_svalue *>::test (const svalue *sval)
+{
+ return sval->get_kind () == SK_BITS_WITHIN;
+}
+
+template <> struct default_hash_traits<bits_within_svalue::key_t>
+: public member_function_hash_traits<bits_within_svalue::key_t>
+{
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -888,9 +1101,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
function_point m_point;
@@ -952,7 +1165,7 @@ is_a_helper <widening_svalue *>::test (svalue *sval)
template <> struct default_hash_traits<widening_svalue::key_t>
: public member_function_hash_traits<widening_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
@@ -1000,9 +1213,9 @@ public:
}
void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
+ void mark_empty () { m_type = reinterpret_cast<tree> (2); }
bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
tree m_type;
const binding_map *m_map_ptr;
@@ -1029,6 +1242,11 @@ public:
return key_t (get_type (), &m_map);
}
+ const svalue *
+ maybe_fold_bits_within (tree type,
+ const bit_range &subrange,
+ region_model_manager *mgr) const FINAL OVERRIDE;
+
private:
static complexity calc_complexity (const binding_map &map);
@@ -1048,7 +1266,7 @@ is_a_helper <compound_svalue *>::test (svalue *sval)
template <> struct default_hash_traits<compound_svalue::key_t>
: public member_function_hash_traits<compound_svalue::key_t>
{
- static const bool empty_zero_p = true;
+ static const bool empty_zero_p = false;
};
namespace ana {
diff --git a/gcc/btfout.c b/gcc/btfout.c
index e58c969..8cdd990 100644
--- a/gcc/btfout.c
+++ b/gcc/btfout.c
@@ -124,6 +124,7 @@ get_btf_kind (uint32_t ctf_kind)
switch (ctf_kind)
{
case CTF_K_INTEGER: return BTF_KIND_INT;
+ case CTF_K_FLOAT: return BTF_KIND_FLOAT;
case CTF_K_POINTER: return BTF_KIND_PTR;
case CTF_K_ARRAY: return BTF_KIND_ARRAY;
case CTF_K_FUNCTION: return BTF_KIND_FUNC_PROTO;
@@ -627,6 +628,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
switch (btf_kind)
{
case BTF_KIND_INT:
+ case BTF_KIND_FLOAT:
case BTF_KIND_STRUCT:
case BTF_KIND_UNION:
case BTF_KIND_ENUM:
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e5e3938..39ab139 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -206,6 +206,7 @@ access_ref::access_ref (tree bound /* = NULL_TREE */,
{
/* Set to valid. */
offrng[0] = offrng[1] = 0;
+ offmax[0] = offmax[1] = 0;
/* Invalidate. */
sizrng[0] = sizrng[1] = -1;
@@ -457,6 +458,21 @@ access_ref::size_remaining (offset_int *pmin /* = NULL */) const
return sizrng[1] - or0;
}
+/* Return true if the offset and object size are in range for SIZE. */
+
+bool
+access_ref::offset_in_range (const offset_int &size) const
+{
+ if (size_remaining () < size)
+ return false;
+
+ if (base0)
+ return offmax[0] >= 0 && offmax[1] <= sizrng[1];
+
+ offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
+ return offmax[0] > -maxoff && offmax[1] < maxoff;
+}
+
/* Add the range [MIN, MAX] to the offset range. For known objects (with
zero-based offsets) at least one of whose offset's bounds is in range,
constrain the other (or both) to the bounds of the object (i.e., zero
@@ -493,6 +509,8 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
if (max >= 0)
{
offrng[0] = 0;
+ if (offmax[0] > 0)
+ offmax[0] = 0;
return;
}
@@ -509,6 +527,12 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
offrng[0] = 0;
}
+ /* Set the minimum and maximmum computed so far. */
+ if (offrng[1] < 0 && offrng[1] < offmax[0])
+ offmax[0] = offrng[1];
+ if (offrng[0] > 0 && offrng[0] > offmax[1])
+ offmax[1] = offrng[0];
+
if (!base0)
return;
@@ -1126,30 +1150,30 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname,
{
if (wi::ltu_p (maxsiz, bndrng[0]))
warned = warning_at (loc, opt,
- "%K%qD specified bound %s exceeds "
+ "%qD specified bound %s exceeds "
"maximum object size %E",
- expr, func, bndstr, maxobjsize);
+ func, bndstr, maxobjsize);
else
{
bool maybe = wi::to_wide (size) == bndrng[0];
warned = warning_at (loc, opt,
exact
- ? G_("%K%qD specified bound %s exceeds "
+ ? G_("%qD specified bound %s exceeds "
"the size %E of unterminated array")
: (maybe
- ? G_("%K%qD specified bound %s may "
+ ? G_("%qD specified bound %s may "
"exceed the size of at most %E "
"of unterminated array")
- : G_("%K%qD specified bound %s exceeds "
+ : G_("%qD specified bound %s exceeds "
"the size of at most %E "
"of unterminated array")),
- expr, func, bndstr, size);
+ func, bndstr, size);
}
}
else
warned = warning_at (loc, opt,
- "%K%qD argument missing terminating nul",
- expr, func);
+ "%qD argument missing terminating nul",
+ func);
}
else
{
@@ -3969,35 +3993,34 @@ maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func,
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound %E may "
+ ? G_("%qD specified bound %E may "
"exceed maximum object size %E")
- : G_("%K%qD specified bound %E "
+ : G_("%qD specified bound %E "
"exceeds maximum object size %E")),
- exp, func, bndrng[0], maxobjsize)
+ func, bndrng[0], maxobjsize)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound %E may "
+ ? G_("specified bound %E may "
"exceed maximum object size %E")
- : G_("%Kspecified bound %E "
+ : G_("specified bound %E "
"exceeds maximum object size %E")),
- exp, bndrng[0], maxobjsize));
+ bndrng[0], maxobjsize));
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound [%E, %E] may "
+ ? G_("%qD specified bound [%E, %E] may "
"exceed maximum object size %E")
- : G_("%K%qD specified bound [%E, %E] "
+ : G_("%qD specified bound [%E, %E] "
"exceeds maximum object size %E")),
- exp, func,
- bndrng[0], bndrng[1], maxobjsize)
+ func, bndrng[0], bndrng[1], maxobjsize)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound [%E, %E] may "
+ ? G_("specified bound [%E, %E] may "
"exceed maximum object size %E")
- : G_("%Kspecified bound [%E, %E] "
+ : G_("specified bound [%E, %E] "
"exceeds maximum object size %E")),
- exp, bndrng[0], bndrng[1], maxobjsize));
+ bndrng[0], bndrng[1], maxobjsize));
}
else if (!size || tree_int_cst_le (bndrng[0], size))
return false;
@@ -4005,34 +4028,34 @@ maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func,
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound %E may exceed "
+ ? G_("%qD specified bound %E may exceed "
"source size %E")
- : G_("%K%qD specified bound %E exceeds "
+ : G_("%qD specified bound %E exceeds "
"source size %E")),
- exp, func, bndrng[0], size)
+ func, bndrng[0], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound %E may exceed "
+ ? G_("specified bound %E may exceed "
"source size %E")
- : G_("%Kspecified bound %E exceeds "
+ : G_("specified bound %E exceeds "
"source size %E")),
- exp, bndrng[0], size));
+ bndrng[0], size));
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound [%E, %E] may "
+ ? G_("%qD specified bound [%E, %E] may "
"exceed source size %E")
- : G_("%K%qD specified bound [%E, %E] exceeds "
+ : G_("%qD specified bound [%E, %E] exceeds "
"source size %E")),
- exp, func, bndrng[0], bndrng[1], size)
+ func, bndrng[0], bndrng[1], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound [%E, %E] may exceed "
+ ? G_("specified bound [%E, %E] may exceed "
"source size %E")
- : G_("%Kspecified bound [%E, %E] exceeds "
+ : G_("specified bound [%E, %E] exceeds "
"source size %E")),
- exp, bndrng[0], bndrng[1], size));
+ bndrng[0], bndrng[1], size));
if (warned)
{
if (pad && pad->src.ref)
@@ -4057,35 +4080,34 @@ maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func,
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified size %E may "
+ ? G_("%qD specified size %E may "
"exceed maximum object size %E")
- : G_("%K%qD specified size %E "
+ : G_("%qD specified size %E "
"exceeds maximum object size %E")),
- exp, func, bndrng[0], maxobjsize)
+ func, bndrng[0], maxobjsize)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified size %E may exceed "
+ ? G_("specified size %E may exceed "
"maximum object size %E")
- : G_("%Kspecified size %E exceeds "
+ : G_("specified size %E exceeds "
"maximum object size %E")),
- exp, bndrng[0], maxobjsize));
+ bndrng[0], maxobjsize));
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified size between %E and %E "
+ ? G_("%qD specified size between %E and %E "
"may exceed maximum object size %E")
- : G_("%K%qD specified size between %E and %E "
+ : G_("%qD specified size between %E and %E "
"exceeds maximum object size %E")),
- exp, func,
- bndrng[0], bndrng[1], maxobjsize)
+ func, bndrng[0], bndrng[1], maxobjsize)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified size between %E and %E "
+ ? G_("specified size between %E and %E "
"may exceed maximum object size %E")
- : G_("%Kspecified size between %E and %E "
+ : G_("specified size between %E and %E "
"exceeds maximum object size %E")),
- exp, bndrng[0], bndrng[1], maxobjsize));
+ bndrng[0], bndrng[1], maxobjsize));
}
else if (!size || tree_int_cst_le (bndrng[0], size))
return false;
@@ -4093,34 +4115,34 @@ maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func,
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound %E may exceed "
+ ? G_("%qD specified bound %E may exceed "
"destination size %E")
- : G_("%K%qD specified bound %E exceeds "
+ : G_("%qD specified bound %E exceeds "
"destination size %E")),
- exp, func, bndrng[0], size)
+ func, bndrng[0], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound %E may exceed "
+ ? G_("specified bound %E may exceed "
"destination size %E")
- : G_("%Kspecified bound %E exceeds "
+ : G_("specified bound %E exceeds "
"destination size %E")),
- exp, bndrng[0], size));
+ bndrng[0], size));
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD specified bound [%E, %E] may exceed "
+ ? G_("%qD specified bound [%E, %E] may exceed "
"destination size %E")
- : G_("%K%qD specified bound [%E, %E] exceeds "
+ : G_("%qD specified bound [%E, %E] exceeds "
"destination size %E")),
- exp, func, bndrng[0], bndrng[1], size)
+ func, bndrng[0], bndrng[1], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kspecified bound [%E, %E] exceeds "
+ ? G_("specified bound [%E, %E] exceeds "
"destination size %E")
- : G_("%Kspecified bound [%E, %E] exceeds "
+ : G_("specified bound [%E, %E] exceeds "
"destination size %E")),
- exp, bndrng[0], bndrng[1], size));
+ bndrng[0], bndrng[1], size));
if (warned)
{
@@ -4158,65 +4180,63 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
warned = (func
? warning_n (loc, opt, tree_to_uhwi (range[0]),
(maybe
- ? G_("%K%qD may access %E byte in a region "
+ ? G_("%qD may access %E byte in a region "
"of size %E")
- : G_("%K%qD accessing %E byte in a region "
+ : G_("%qD accessing %E byte in a region "
"of size %E")),
(maybe
- ? G_ ("%K%qD may access %E bytes in a region "
+ ? G_ ("%qD may access %E bytes in a region "
"of size %E")
- : G_ ("%K%qD accessing %E bytes in a region "
+ : G_ ("%qD accessing %E bytes in a region "
"of size %E")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_n (loc, opt, tree_to_uhwi (range[0]),
(maybe
- ? G_("%Kmay access %E byte in a region "
+ ? G_("may access %E byte in a region "
"of size %E")
- : G_("%Kaccessing %E byte in a region "
+ : G_("accessing %E byte in a region "
"of size %E")),
(maybe
- ? G_("%Kmay access %E bytes in a region "
+ ? G_("may access %E bytes in a region "
"of size %E")
- : G_("%Kaccessing %E bytes in a region "
+ : G_("accessing %E bytes in a region "
"of size %E")),
- exp, range[0], size));
+ 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,
(maybe
- ? G_("%K%qD may access %E or more bytes "
+ ? G_("%qD may access %E or more bytes "
"in a region of size %E")
- : G_("%K%qD accessing %E or more bytes "
+ : G_("%qD accessing %E or more bytes "
"in a region of size %E")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kmay access %E or more bytes "
+ ? G_("may access %E or more bytes "
"in a region of size %E")
- : G_("%Kaccessing %E or more bytes "
+ : G_("accessing %E or more bytes "
"in a region of size %E")),
- exp, range[0], size));
+ range[0], size));
}
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD may access between %E and %E "
+ ? G_("%qD may access between %E and %E "
"bytes in a region of size %E")
- : G_("%K%qD accessing between %E and %E "
+ : G_("%qD accessing between %E and %E "
"bytes in a region of size %E")),
- exp, func, range[0], range[1],
- size)
+ func, range[0], range[1], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kmay access between %E and %E bytes "
+ ? G_("may access between %E and %E bytes "
"in a region of size %E")
- : G_("%Kaccessing between %E and %E bytes "
+ : G_("accessing between %E and %E bytes "
"in a region of size %E")),
- exp, range[0], range[1],
- size));
+ range[0], range[1], size));
return warned;
}
@@ -4226,69 +4246,67 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
warned = (func
? warning_n (loc, opt, tree_to_uhwi (range[0]),
(maybe
- ? G_("%K%qD may write %E byte into a region "
+ ? G_("%qD may write %E byte into a region "
"of size %E")
- : G_("%K%qD writing %E byte into a region "
+ : G_("%qD writing %E byte into a region "
"of size %E overflows the destination")),
(maybe
- ? G_("%K%qD may write %E bytes into a region "
+ ? G_("%qD may write %E bytes into a region "
"of size %E")
- : G_("%K%qD writing %E bytes into a region "
+ : G_("%qD writing %E bytes into a region "
"of size %E overflows the destination")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_n (loc, opt, tree_to_uhwi (range[0]),
(maybe
- ? G_("%Kmay write %E byte into a region "
+ ? G_("may write %E byte into a region "
"of size %E")
- : G_("%Kwriting %E byte into a region "
+ : G_("writing %E byte into a region "
"of size %E overflows the destination")),
(maybe
- ? G_("%Kmay write %E bytes into a region "
+ ? G_("may write %E bytes into a region "
"of size %E")
- : G_("%Kwriting %E bytes into a region "
+ : G_("writing %E bytes into a region "
"of size %E overflows the destination")),
- exp, range[0], size));
+ 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,
(maybe
- ? G_("%K%qD may write %E or more bytes "
+ ? G_("%qD may write %E or more bytes "
"into a region of size %E")
- : G_("%K%qD writing %E or more bytes "
+ : G_("%qD writing %E or more bytes "
"into a region of size %E overflows "
"the destination")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kmay write %E or more bytes into "
+ ? G_("may write %E or more bytes into "
"a region of size %E")
- : G_("%Kwriting %E or more bytes into "
+ : G_("writing %E or more bytes into "
"a region of size %E overflows "
"the destination")),
- exp, range[0], size));
+ range[0], size));
}
else
warned = (func
? warning_at (loc, opt,
(maybe
- ? G_("%K%qD may write between %E and %E bytes "
+ ? G_("%qD may write between %E and %E bytes "
"into a region of size %E")
- : G_("%K%qD writing between %E and %E bytes "
+ : G_("%qD writing between %E and %E bytes "
"into a region of size %E overflows "
"the destination")),
- exp, func, range[0], range[1],
- size)
+ func, range[0], range[1], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kmay write between %E and %E bytes "
+ ? G_("may write between %E and %E bytes "
"into a region of size %E")
- : G_("%Kwriting between %E and %E bytes "
+ : G_("writing between %E and %E bytes "
"into a region of size %E overflows "
"the destination")),
- exp, range[0], range[1],
- size));
+ range[0], range[1], size));
return warned;
}
@@ -4299,64 +4317,64 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
? warning_n (loc, OPT_Wstringop_overread,
tree_to_uhwi (range[0]),
(maybe
- ? G_("%K%qD may read %E byte from a region "
+ ? G_("%qD may read %E byte from a region "
"of size %E")
- : G_("%K%qD reading %E byte from a region "
+ : G_("%qD reading %E byte from a region "
"of size %E")),
(maybe
- ? G_("%K%qD may read %E bytes from a region "
+ ? G_("%qD may read %E bytes from a region "
"of size %E")
- : G_("%K%qD reading %E bytes from a region "
+ : G_("%qD reading %E bytes from a region "
"of size %E")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_n (loc, OPT_Wstringop_overread,
tree_to_uhwi (range[0]),
(maybe
- ? G_("%Kmay read %E byte from a region "
+ ? G_("may read %E byte from a region "
"of size %E")
- : G_("%Kreading %E byte from a region "
+ : G_("reading %E byte from a region "
"of size %E")),
(maybe
- ? G_("%Kmay read %E bytes from a region "
+ ? G_("may read %E bytes from a region "
"of size %E")
- : G_("%Kreading %E bytes from a region "
+ : G_("reading %E bytes from a region "
"of size %E")),
- exp, range[0], size));
+ 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,
(maybe
- ? G_("%K%qD may read %E or more bytes "
+ ? G_("%qD may read %E or more bytes "
"from a region of size %E")
- : G_("%K%qD reading %E or more bytes "
+ : G_("%qD reading %E or more bytes "
"from a region of size %E")),
- exp, func, range[0], size)
+ func, range[0], size)
: warning_at (loc, OPT_Wstringop_overread,
(maybe
- ? G_("%Kmay read %E or more bytes "
+ ? G_("may read %E or more bytes "
"from a region of size %E")
- : G_("%Kreading %E or more bytes "
+ : G_("reading %E or more bytes "
"from a region of size %E")),
- exp, range[0], size));
+ range[0], size));
}
else
warned = (func
? warning_at (loc, OPT_Wstringop_overread,
(maybe
- ? G_("%K%qD may read between %E and %E bytes "
+ ? G_("%qD may read between %E and %E bytes "
"from a region of size %E")
- : G_("%K%qD reading between %E and %E bytes "
+ : G_("%qD reading between %E and %E bytes "
"from a region of size %E")),
- exp, func, range[0], range[1], size)
+ func, range[0], range[1], size)
: warning_at (loc, opt,
(maybe
- ? G_("%Kmay read between %E and %E bytes "
+ ? G_("may read between %E and %E bytes "
"from a region of size %E")
- : G_("%Kreading between %E and %E bytes "
+ : G_("reading between %E and %E bytes "
"from a region of size %E")),
- exp, range[0], range[1], size));
+ range[0], range[1], size));
if (warned)
suppress_warning (exp, OPT_Wstringop_overread);
@@ -4369,37 +4387,37 @@ 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 expecting %E byte in a region of size %E",
- "%K%qD expecting %E bytes in a region of size %E",
- exp, func, range[0], size)
+ "%qD expecting %E byte in a region of size %E",
+ "%qD expecting %E bytes in a region of size %E",
+ func, range[0], size)
: warning_n (loc, OPT_Wstringop_overread,
tree_to_uhwi (range[0]),
- "%Kexpecting %E byte in a region of size %E",
- "%Kexpecting %E bytes in a region of size %E",
- exp, range[0], size));
+ "expecting %E byte in a region of size %E",
+ "expecting %E bytes in a region of size %E",
+ 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 expecting %E or more bytes in a region "
+ "%qD expecting %E or more bytes in a region "
"of size %E",
- exp, func, range[0], size)
+ func, range[0], size)
: warning_at (loc, OPT_Wstringop_overread,
- "%Kexpecting %E or more bytes in a region "
+ "expecting %E or more bytes in a region "
"of size %E",
- exp, range[0], size));
+ range[0], size));
}
else
warned = (func
? warning_at (loc, OPT_Wstringop_overread,
- "%K%qD expecting between %E and %E bytes in "
+ "%qD expecting between %E and %E bytes in "
"a region of size %E",
- exp, func, range[0], range[1], size)
+ func, range[0], range[1], size)
: warning_at (loc, OPT_Wstringop_overread,
- "%Kexpecting between %E and %E bytes in "
+ "expecting between %E and %E bytes in "
"a region of size %E",
- exp, range[0], range[1], size));
+ range[0], range[1], size));
if (warned)
suppress_warning (exp, OPT_Wstringop_overread);
@@ -4577,23 +4595,46 @@ access_ref::inform_access (access_mode mode) const
return;
}
+ if (mode == access_read_only)
+ {
+ if (allocfn == NULL_TREE)
+ {
+ if (*offstr)
+ inform (loc, "at offset %s into source object %qE of size %s",
+ offstr, ref, sizestr);
+ else
+ inform (loc, "source object %qE of size %s", ref, sizestr);
+
+ return;
+ }
+
+ if (*offstr)
+ inform (loc,
+ "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);
+ return;
+ }
+
if (allocfn == NULL_TREE)
{
if (*offstr)
- inform (loc, "at offset %s into source object %qE of size %s",
+ inform (loc, "at offset %s into object %qE of size %s",
offstr, ref, sizestr);
else
- inform (loc, "source object %qE of size %s", ref, sizestr);
+ inform (loc, "object %qE of size %s", ref, sizestr);
return;
}
if (*offstr)
inform (loc,
- "at offset %s into source object of size %s allocated by %qE",
+ "at offset %s into object of size %s allocated by %qE",
offstr, sizestr, allocfn);
else
- inform (loc, "source object of size %s allocated by %qE",
+ inform (loc, "object of size %s allocated by %qE",
sizestr, allocfn);
}
@@ -4759,7 +4800,7 @@ check_access (tree exp, tree dstwrite,
&& TREE_CODE (range[0]) == INTEGER_CST
&& tree_int_cst_lt (maxobjsize, range[0]))
{
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
maybe_warn_for_bound (OPT_Wstringop_overflow_, loc, exp, func, range,
NULL_TREE, pad);
return false;
@@ -4787,7 +4828,7 @@ check_access (tree exp, tree dstwrite,
&& warning_suppressed_p (pad->dst.ref, opt)))
return false;
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
bool warned = false;
if (dstwrite == slen && at_least_one)
{
@@ -4796,15 +4837,15 @@ check_access (tree exp, tree dstwrite,
at least one byte past the end of the destination. */
warned = (func
? warning_at (loc, opt,
- "%K%qD writing %E or more bytes into "
+ "%qD writing %E or more bytes into "
"a region of size %E overflows "
"the destination",
- exp, func, range[0], dstsize)
+ func, range[0], dstsize)
: warning_at (loc, opt,
- "%Kwriting %E or more bytes into "
+ "writing %E or more bytes into "
"a region of size %E overflows "
"the destination",
- exp, range[0], dstsize));
+ range[0], dstsize));
}
else
{
@@ -4840,7 +4881,7 @@ check_access (tree exp, tree dstwrite,
PAD is nonnull and BNDRNG is valid. */
get_size_range (maxread, range, pad ? pad->src.bndrng : NULL);
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
tree size = dstsize;
if (pad && pad->mode == access_read_only)
size = wide_int_to_tree (sizetype, pad->src.sizrng[1]);
@@ -4901,7 +4942,7 @@ check_access (tree exp, tree dstwrite,
&& warning_suppressed_p (pad->src.ref, opt)))
return false;
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
const bool read
= mode == access_read_only || mode == access_read_write;
const bool maybe = pad && pad->dst.parmarray;
@@ -5439,16 +5480,16 @@ handle_mem_ref (tree mref, int ostype, access_ref *pref,
if (VECTOR_TYPE_P (TREE_TYPE (mref)))
{
- /* Hack: Give up for MEM_REFs of vector types; those may be
- synthesized from multiple assignments to consecutive data
- members (see PR 93200 and 96963).
+ /* Hack: Handle MEM_REFs of vector types as those to complete
+ objects; those may be synthesized from multiple assignments
+ to consecutive data members (see PR 93200 and 96963).
FIXME: Vectorized assignments should only be present after
vectorization so this hack is only necessary after it has
run and could be avoided in calls from prior passes (e.g.,
tree-ssa-strlen.c).
FIXME: Deal with this more generally, e.g., by marking up
such MEM_REFs at the time they're created. */
- return false;
+ ostype = 0;
}
tree mrefop = TREE_OPERAND (mref, 0);
@@ -5802,6 +5843,12 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref,
tree rhs = gimple_assign_rhs1 (stmt);
+ if (code == ASSERT_EXPR)
+ {
+ rhs = TREE_OPERAND (rhs, 0);
+ return compute_objsize_r (rhs, ostype, pref, snlim, qry);
+ }
+
if (code == POINTER_PLUS_EXPR
&& TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
{
@@ -6481,10 +6528,10 @@ check_strncat_sizes (tree exp, tree objsize)
if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (objsize)
&& tree_int_cst_equal (objsize, maxread))
{
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
warning_at (loc, OPT_Wstringop_overflow_,
- "%K%qD specified bound %E equals destination size",
- exp, get_callee_fndecl (exp), maxread);
+ "%qD specified bound %E equals destination size",
+ get_callee_fndecl (exp), maxread);
return false;
}
@@ -6554,10 +6601,10 @@ expand_builtin_strncat (tree exp, rtx)
if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (destsize)
&& tree_int_cst_equal (destsize, maxread))
{
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
warning_at (loc, OPT_Wstringop_overflow_,
- "%K%qD specified bound %E equals destination size",
- exp, get_callee_fndecl (exp), maxread);
+ "%qD specified bound %E equals destination size",
+ get_callee_fndecl (exp), maxread);
return NULL_RTX;
}
@@ -7330,7 +7377,7 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
|| !check_nul_terminated_array (exp, arg2, arg3))
return NULL_RTX;
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
tree len1 = c_strlen (arg1, 1);
tree len2 = c_strlen (arg2, 1);
@@ -10006,13 +10053,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
case BUILT_IN_VA_ARG_PACK:
/* All valid uses of __builtin_va_arg_pack () are removed during
inlining. */
- error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
+ error ("invalid use of %<__builtin_va_arg_pack ()%>");
return const0_rtx;
case BUILT_IN_VA_ARG_PACK_LEN:
/* All valid uses of __builtin_va_arg_pack_len () are removed during
inlining. */
- error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
+ error ("invalid use of %<__builtin_va_arg_pack_len ()%>");
return const0_rtx;
/* Return the address of the first anonymous stack arg. */
@@ -12961,8 +13008,8 @@ expand_builtin_object_size (tree exp)
if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
{
- error ("%Kfirst argument of %qD must be a pointer, second integer constant",
- exp, fndecl);
+ error ("first argument of %qD must be a pointer, second integer constant",
+ fndecl);
expand_builtin_trap ();
return const0_rtx;
}
@@ -12974,8 +13021,8 @@ expand_builtin_object_size (tree exp)
|| tree_int_cst_sgn (ost) < 0
|| compare_tree_int (ost, 3) > 0)
{
- error ("%Klast argument of %qD is not integer constant between 0 and 3",
- exp, fndecl);
+ error ("last argument of %qD is not integer constant between 0 and 3",
+ fndecl);
expand_builtin_trap ();
return const0_rtx;
}
@@ -13787,8 +13834,8 @@ warn_dealloc_offset (location_t loc, tree exp, const access_ref &aref)
}
if (!warning_at (loc, OPT_Wfree_nonheap_object,
- "%K%qD called on pointer %qE with nonzero offset%s",
- exp, dealloc_decl, aref.ref, offstr))
+ "%qD called on pointer %qE with nonzero offset%s",
+ dealloc_decl, aref.ref, offstr))
return false;
if (DECL_P (aref.ref))
@@ -13843,15 +13890,15 @@ maybe_emit_free_warning (tree exp)
return;
tree dealloc_decl = get_callee_fndecl (exp);
- location_t loc = tree_inlined_location (exp);
+ location_t loc = EXPR_LOCATION (exp);
if (DECL_P (ref) || EXPR_P (ref))
{
/* Diagnose freeing a declared object. */
if (aref.ref_declared ()
&& warning_at (loc, OPT_Wfree_nonheap_object,
- "%K%qD called on unallocated object %qD",
- exp, dealloc_decl, ref))
+ "%qD called on unallocated object %qD",
+ dealloc_decl, ref))
{
loc = (DECL_P (ref)
? DECL_SOURCE_LOCATION (ref)
@@ -13870,8 +13917,8 @@ maybe_emit_free_warning (tree exp)
else if (CONSTANT_CLASS_P (ref))
{
if (warning_at (loc, OPT_Wfree_nonheap_object,
- "%K%qD called on a pointer to an unallocated "
- "object %qE", exp, dealloc_decl, ref))
+ "%qD called on a pointer to an unallocated "
+ "object %qE", dealloc_decl, ref))
{
if (TREE_CODE (ptr) == SSA_NAME)
{
@@ -13909,18 +13956,18 @@ maybe_emit_free_warning (tree exp)
? OPT_Wmismatched_new_delete
: OPT_Wmismatched_dealloc);
warned = warning_at (loc, opt,
- "%K%qD called on pointer returned "
+ "%qD called on pointer returned "
"from a mismatched allocation "
- "function", exp, dealloc_decl);
+ "function", dealloc_decl);
}
}
else if (gimple_call_builtin_p (def_stmt, BUILT_IN_ALLOCA)
|| gimple_call_builtin_p (def_stmt,
BUILT_IN_ALLOCA_WITH_ALIGN))
warned = warning_at (loc, OPT_Wfree_nonheap_object,
- "%K%qD called on pointer to "
+ "%qD called on pointer to "
"an unallocated object",
- exp, dealloc_decl);
+ dealloc_decl);
else if (warn_dealloc_offset (loc, exp, aref))
return;
diff --git a/gcc/builtins.h b/gcc/builtins.h
index e71f40c..a64ece3 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -222,6 +222,9 @@ struct access_ref
argument to the minimum. */
offset_int size_remaining (offset_int * = NULL) const;
+/* Return true if the offset and object size are in range for SIZE. */
+ bool offset_in_range (const offset_int &) const;
+
/* Return true if *THIS is an access to a declared object. */
bool ref_declared () const
{
@@ -261,6 +264,8 @@ struct access_ref
/* Range of byte offsets into and sizes of the object(s). */
offset_int offrng[2];
offset_int sizrng[2];
+ /* The minimum and maximum offset computed. */
+ offset_int offmax[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
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index fe6a44c..0f1b45d 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,32 @@
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * c-format.c (gcc_tdiag_char_table): Remove support for %G and %K.
+ (gcc_cdiag_char_table): Same.
+ (gcc_cxxdiag_char_table): Same.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.h (enum c_omp_directive_kind): New enum.
+ (struct c_omp_directive): New type.
+ (c_omp_categorize_directive): Declare.
+ * c-omp.c (omp_directives): New variable.
+ (c_omp_categorize_directive): New function.
+
+2021-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (packed_layout): New global variable.
+ (dump_ada_declaration): Set it upon seeing a packed record type.
+ Do not put the "aliased" keyword if it is set.
+ (dump_ada_structure): Add Pack aspect if it is set and clear it.
+
+2021-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (check_name): Rename into...
+ (check_type_name_conflict): ...this. Minor tweak.
+ (dump_ada_function_declaration): Adjust to above renaming.
+ (dump_ada_array_domains): Fix oversight.
+ (dump_ada_declaration): Call check_type_name_conflict for variables.
+
2021-06-25 Martin Sebor <msebor@redhat.com>
* c-common.c (c_wrap_maybe_const): Remove TREE_NO_WARNING.
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index a2669c6..827bcc7 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -1540,9 +1540,8 @@ dump_ada_import (pretty_printer *buffer, tree t, int spc)
otherwise in BUFFER. */
static void
-check_name (pretty_printer *buffer, tree t)
+check_type_name_conflict (pretty_printer *buffer, tree t)
{
- const char *s;
tree tmp = TREE_TYPE (t);
while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
@@ -1550,6 +1549,8 @@ check_name (pretty_printer *buffer, tree t)
if (TREE_CODE (tmp) != FUNCTION_TYPE)
{
+ const char *s;
+
if (TREE_CODE (tmp) == IDENTIFIER_NODE)
s = IDENTIFIER_POINTER (tmp);
else if (!TYPE_NAME (tmp))
@@ -1641,7 +1642,7 @@ dump_ada_function_declaration (pretty_printer *buffer, tree func,
{
if (DECL_NAME (arg))
{
- check_name (buffer, arg);
+ check_type_name_conflict (buffer, arg);
pp_ada_tree_identifier (buffer, DECL_NAME (arg), NULL_TREE,
false);
pp_string (buffer, " : ");
@@ -1710,7 +1711,8 @@ dump_ada_function_declaration (pretty_printer *buffer, tree func,
static void
dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
{
- int first = 1;
+ bool first = true;
+
pp_left_paren (buffer);
for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
@@ -1724,7 +1726,7 @@ dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
if (!first)
pp_string (buffer, ", ");
- first = 0;
+ first = false;
if (min)
dump_ada_node (buffer, min, NULL_TREE, spc, false, true);
@@ -1738,7 +1740,10 @@ dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
pp_string (buffer, "0");
}
else
- pp_string (buffer, "size_t");
+ {
+ pp_string (buffer, "size_t");
+ first = false;
+ }
}
pp_right_paren (buffer);
}
@@ -2033,6 +2038,7 @@ is_float128 (tree node)
}
static bool bitfield_used = false;
+static bool packed_layout = false;
/* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
@@ -2846,14 +2852,14 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
return 1;
}
- /* ??? Packed record layout is not supported. */
+ /* Packed record layout is not fully supported. */
if (TYPE_PACKED (TREE_TYPE (t)))
{
- warning_at (DECL_SOURCE_LOCATION (t), 0,
- "unsupported record layout");
+ warning_at (DECL_SOURCE_LOCATION (t), 0, "packed layout");
pp_string (buffer, "pragma Compile_Time_Warning (True, ");
- pp_string (buffer, "\"probably incorrect record layout\");");
+ pp_string (buffer, "\"packed layout may be incorrect\");");
newline_and_indent (buffer, spc);
+ packed_layout = true;
}
if (orig && TYPE_NAME (orig))
@@ -2946,7 +2952,8 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
pp_string (buffer, " : ");
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE)
+ if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE
+ && !packed_layout)
pp_string (buffer, "aliased ");
if (TYPE_NAME (TREE_TYPE (t)))
@@ -3152,8 +3159,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
if (need_indent)
INDENT (spc);
- if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t))
- check_name (buffer, t);
+ if ((TREE_CODE (t) == FIELD_DECL || TREE_CODE (t) == VAR_DECL)
+ && DECL_NAME (t))
+ check_type_name_conflict (buffer, t);
/* Print variable/type's name. */
dump_ada_node (buffer, t, t, spc, false, true);
@@ -3179,7 +3187,8 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
&& (TYPE_NAME (TREE_TYPE (t))
|| (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)))
+ && TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE))
+ && !packed_layout)
pp_string (buffer, "aliased ");
if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
@@ -3346,7 +3355,7 @@ dump_ada_structure (pretty_printer *buffer, tree node, tree type, bool nested,
pp_string (buffer, "Unchecked_Union => True");
}
- if (bitfield_used)
+ if (bitfield_used || packed_layout)
{
char buf[32];
pp_comma (buffer);
@@ -3357,6 +3366,7 @@ dump_ada_structure (pretty_printer *buffer, tree node, tree type, bool nested,
sprintf (buf, "Alignment => %d", TYPE_ALIGN (node) / BITS_PER_UNIT);
pp_string (buffer, buf);
bitfield_used = false;
+ packed_layout = false;
}
if (nested)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 88022d0..50ca8fb 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1246,6 +1246,25 @@ extern void c_omp_mark_declare_variant (location_t, tree, tree);
extern const char *c_omp_map_clause_name (tree, bool);
extern void c_omp_adjust_map_clauses (tree, bool);
+enum c_omp_directive_kind {
+ C_OMP_DIR_STANDALONE,
+ C_OMP_DIR_CONSTRUCT,
+ C_OMP_DIR_DECLARATIVE,
+ C_OMP_DIR_UTILITY,
+ C_OMP_DIR_INFORMATIONAL
+};
+
+struct c_omp_directive {
+ const char *first, *second, *third;
+ unsigned int id;
+ enum c_omp_directive_kind kind;
+ bool simd;
+};
+
+extern const struct c_omp_directive *c_omp_categorize_directive (const char *,
+ const char *,
+ const char *);
+
/* Return next tree in the chain for chain_next walking of tree nodes. */
static inline tree
c_tree_chain_next (tree t)
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index bda3b18..6fd0bb3 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -781,10 +781,6 @@ static const format_char_info gcc_tdiag_char_table[] =
/* These will require a "tree" at runtime. */
{ "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL },
{ "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
- { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
-
- /* G requires a "gimple*" argument at runtime. */
- { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
@@ -799,10 +795,6 @@ static const format_char_info gcc_cdiag_char_table[] =
/* These will require a "tree" at runtime. */
{ "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL },
{ "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
- { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
-
- /* G requires a "gimple*" argument at runtime. */
- { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
{ "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
@@ -819,10 +811,6 @@ static const format_char_info gcc_cxxdiag_char_table[] =
/* These will require a "tree" at runtime. */
{ "ADFHISTVX",1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "'", NULL },
{ "E", 1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
- { "K", 1, STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
-
- /* G requires a "gimple*" argument at runtime. */
- { "G", 1, STD_C89,{ T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
/* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index cd81a08..e70974d 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -2912,3 +2912,154 @@ c_omp_adjust_map_clauses (tree clauses, bool is_target)
}
}
}
+
+static const struct c_omp_directive omp_directives[] = {
+ /* Keep this alphabetically sorted by the first word. Non-null second/third
+ if any should precede null ones. */
+ { "allocate", nullptr, nullptr, PRAGMA_OMP_ALLOCATE,
+ C_OMP_DIR_DECLARATIVE, false },
+ /* { "assume", nullptr, nullptr, PRAGMA_OMP_ASSUME,
+ C_OMP_DIR_INFORMATIONAL, false }, */
+ /* { "assumes", nullptr, nullptr, PRAGMA_OMP_ASSUMES,
+ C_OMP_DIR_INFORMATIONAL, false }, */
+ { "atomic", nullptr, nullptr, PRAGMA_OMP_ATOMIC,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "barrier", nullptr, nullptr, PRAGMA_OMP_BARRIER,
+ C_OMP_DIR_STANDALONE, false },
+ /* { "begin", "assumes", nullptr, PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_INFORMATIONAL, false }, */
+ /* { "begin", "declare", "target", PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_DECLARATIVE, false }, */
+ /* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_DECLARATIVE, false }, */
+ /* { "begin", "metadirective", nullptr, PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_???, ??? }, */
+ { "cancel", nullptr, nullptr, PRAGMA_OMP_CANCEL,
+ C_OMP_DIR_STANDALONE, false },
+ { "cancellation", "point", nullptr, PRAGMA_OMP_CANCELLATION_POINT,
+ C_OMP_DIR_STANDALONE, false },
+ { "critical", nullptr, nullptr, PRAGMA_OMP_CRITICAL,
+ C_OMP_DIR_CONSTRUCT, false },
+ /* { "declare", "mapper", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, false }, */
+ { "declare", "reduction", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, true },
+ { "declare", "simd", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, true },
+ { "declare", "target", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, false },
+ { "declare", "variant", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, false },
+ { "depobj", nullptr, nullptr, PRAGMA_OMP_DEPOBJ,
+ C_OMP_DIR_STANDALONE, false },
+ /* { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
+ C_OMP_DIR_CONSTRUCT, false }, */
+ { "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
+ C_OMP_DIR_CONSTRUCT, true },
+ /* { "end", "assumes", nullptr, PRAGMA_OMP_END,
+ C_OMP_DIR_INFORMATIONAL, false }, */
+ { "end", "declare", "target", PRAGMA_OMP_END_DECLARE_TARGET,
+ C_OMP_DIR_DECLARATIVE, false },
+ /* { "end", "declare", "variant", PRAGMA_OMP_END,
+ C_OMP_DIR_DECLARATIVE, false }, */
+ /* { "end", "metadirective", nullptr, PRAGMA_OMP_END,
+ C_OMP_DIR_???, ??? }, */
+ /* error with at(execution) is C_OMP_DIR_STANDALONE. */
+ /* { "error", nullptr, nullptr, PRAGMA_OMP_ERROR,
+ C_OMP_DIR_UTILITY, false }, */
+ { "flush", nullptr, nullptr, PRAGMA_OMP_FLUSH,
+ C_OMP_DIR_STANDALONE, false },
+ { "for", nullptr, nullptr, PRAGMA_OMP_FOR,
+ C_OMP_DIR_CONSTRUCT, true },
+ /* { "interop", nullptr, nullptr, PRAGMA_OMP_INTEROP,
+ C_OMP_DIR_STANDALONE, false }, */
+ { "loop", nullptr, nullptr, PRAGMA_OMP_LOOP,
+ C_OMP_DIR_CONSTRUCT, true },
+ /* { "masked", nullptr, nullptr, PRAGMA_OMP_MASKED,
+ C_OMP_DIR_CONSTRUCT, true }, */
+ { "master", nullptr, nullptr, PRAGMA_OMP_MASTER,
+ C_OMP_DIR_CONSTRUCT, true },
+ /* { "metadirective", nullptr, nullptr, PRAGMA_OMP_METADIRECTIVE,
+ C_OMP_DIR_???, ??? }, */
+ /* { "nothing", nullptr, nullptr, PRAGMA_OMP_NOTHING,
+ C_OMP_DIR_UTILITY, false }, */
+ /* ordered with depend clause is C_OMP_DIR_STANDALONE. */
+ { "ordered", nullptr, nullptr, PRAGMA_OMP_ORDERED,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "parallel", nullptr, nullptr, PRAGMA_OMP_PARALLEL,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "requires", nullptr, nullptr, PRAGMA_OMP_REQUIRES,
+ C_OMP_DIR_INFORMATIONAL, false },
+ { "scan", nullptr, nullptr, PRAGMA_OMP_SCAN,
+ C_OMP_DIR_CONSTRUCT, true },
+ /* { "scope", nullptr, nullptr, PRAGMA_OMP_SCOPE,
+ C_OMP_DIR_CONSTRUCT, false }, */
+ { "section", nullptr, nullptr, PRAGMA_OMP_SECTION,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "sections", nullptr, nullptr, PRAGMA_OMP_SECTIONS,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "simd", nullptr, nullptr, PRAGMA_OMP_SIMD,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "single", nullptr, nullptr, PRAGMA_OMP_SINGLE,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "target", "data", nullptr, PRAGMA_OMP_TARGET,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "target", "enter", "data", PRAGMA_OMP_TARGET,
+ C_OMP_DIR_STANDALONE, false },
+ { "target", "exit", "data", PRAGMA_OMP_TARGET,
+ C_OMP_DIR_STANDALONE, false },
+ { "target", "update", nullptr, PRAGMA_OMP_TARGET,
+ C_OMP_DIR_STANDALONE, false },
+ { "target", nullptr, nullptr, PRAGMA_OMP_TARGET,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "task", nullptr, nullptr, PRAGMA_OMP_TASK,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "taskgroup", nullptr, nullptr, PRAGMA_OMP_TASKGROUP,
+ C_OMP_DIR_CONSTRUCT, false },
+ { "taskloop", nullptr, nullptr, PRAGMA_OMP_TASKLOOP,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "taskwait", nullptr, nullptr, PRAGMA_OMP_TASKWAIT,
+ C_OMP_DIR_STANDALONE, false },
+ { "taskyield", nullptr, nullptr, PRAGMA_OMP_TASKYIELD,
+ C_OMP_DIR_STANDALONE, false },
+ /* { "tile", nullptr, nullptr, PRAGMA_OMP_TILE,
+ C_OMP_DIR_CONSTRUCT, false }, */
+ { "teams", nullptr, nullptr, PRAGMA_OMP_TEAMS,
+ C_OMP_DIR_CONSTRUCT, true },
+ { "threadprivate", nullptr, nullptr, PRAGMA_OMP_THREADPRIVATE,
+ C_OMP_DIR_DECLARATIVE, false }
+ /* { "unroll", nullptr, nullptr, PRAGMA_OMP_UNROLL,
+ C_OMP_DIR_CONSTRUCT, false }, */
+};
+
+/* Find (non-combined/composite) OpenMP directive (if any) which starts
+ with FIRST keyword and for multi-word directives has SECOND and
+ THIRD keyword after it. */
+
+const struct c_omp_directive *
+c_omp_categorize_directive (const char *first, const char *second,
+ const char *third)
+{
+ const size_t n_omp_directives = ARRAY_SIZE (omp_directives);
+ for (size_t i = 0; i < n_omp_directives; i++)
+ {
+ if ((unsigned char) omp_directives[i].first[0]
+ < (unsigned char) first[0])
+ continue;
+ if ((unsigned char) omp_directives[i].first[0]
+ > (unsigned char) first[0])
+ break;
+ if (strcmp (omp_directives[i].first, first))
+ continue;
+ if (!omp_directives[i].second)
+ return &omp_directives[i];
+ if (!second || strcmp (omp_directives[i].second, second))
+ continue;
+ if (!omp_directives[i].third)
+ return &omp_directives[i];
+ if (!third || strcmp (omp_directives[i].third, third))
+ continue;
+ return &omp_directives[i];
+ }
+ return NULL;
+}
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index ba53da8..ef6f4ad 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * c-objc-common.c (c_tree_printer): Remove support for %G and %K.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/101297
+ * c-parser.c (c_parser_omp_atomic): Consume comma only if it
+ appears before a CPP_NAME.
+
2021-06-25 Martin Sebor <msebor@redhat.com>
* c-decl.c (pop_scope): Replace direct uses of TREE_NO_WARNING with
diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index b945de1..cdb2242 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -247,8 +247,6 @@ print_type (c_pretty_printer *cpp, tree t, bool *quoted)
%D: a general decl,
%E: an identifier or expression,
%F: a function declaration,
- %G: a Gimple statement,
- %K: a CALL_EXPR,
%T: a type.
%V: a list of type qualifiers from a tree.
%v: an explicit list of type qualifiers
@@ -269,19 +267,6 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
if (precision != 0 || wide)
return false;
- if (*spec == 'G')
- {
- percent_G_format (text);
- return true;
- }
-
- if (*spec == 'K')
- {
- t = va_arg (*text->args_ptr, tree);
- percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t));
- return true;
- }
-
if (*spec != 'v')
{
t = va_arg (*text->args_ptr, tree);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 3922b56..9a56e0c 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -17533,7 +17533,9 @@ c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
{
- if (!first && c_parser_next_token_is (parser, CPP_COMMA))
+ if (!first
+ && c_parser_next_token_is (parser, CPP_COMMA)
+ && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
c_parser_consume_token (parser);
first = false;
diff --git a/gcc/calls.c b/gcc/calls.c
index f8a4b79..d2413a2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1435,8 +1435,8 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
if (tree_int_cst_lt (args[i], integer_zero_node))
{
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kargument %i value %qE is negative",
- exp, idx[i] + 1, args[i]);
+ "argument %i value %qE is negative",
+ idx[i] + 1, args[i]);
}
else if (integer_zerop (args[i]))
{
@@ -1452,8 +1452,8 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
: !lookup_attribute ("returns_nonnull",
TYPE_ATTRIBUTES (fntype)))
warned = warning_at (loc, OPT_Walloc_zero,
- "%Kargument %i value is zero",
- exp, idx[i] + 1);
+ "argument %i value is zero",
+ idx[i] + 1);
}
else if (tree_int_cst_lt (maxobjsize, args[i]))
{
@@ -1470,9 +1470,9 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
continue;
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kargument %i value %qE exceeds "
+ "argument %i value %qE exceeds "
"maximum object size %E",
- exp, idx[i] + 1, args[i], maxobjsize);
+ idx[i] + 1, args[i], maxobjsize);
}
}
else if (TREE_CODE (args[i]) == SSA_NAME
@@ -1484,16 +1484,16 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
&& tree_int_cst_le (argrange[i][1], integer_zero_node))
{
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kargument %i range [%E, %E] is negative",
- exp, idx[i] + 1,
+ "argument %i range [%E, %E] is negative",
+ idx[i] + 1,
argrange[i][0], argrange[i][1]);
}
else if (tree_int_cst_lt (maxobjsize, argrange[i][0]))
{
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kargument %i range [%E, %E] exceeds "
+ "argument %i range [%E, %E] exceeds "
"maximum object size %E",
- exp, idx[i] + 1,
+ idx[i] + 1,
argrange[i][0], argrange[i][1],
maxobjsize);
}
@@ -1521,15 +1521,15 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
if (vflow)
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kproduct %<%E * %E%> of arguments %i and %i "
+ "product %<%E * %E%> of arguments %i and %i "
"exceeds %<SIZE_MAX%>",
- exp, argrange[0][0], argrange[1][0],
+ argrange[0][0], argrange[1][0],
idx[0] + 1, idx[1] + 1);
else if (wi::ltu_p (wi::to_wide (maxobjsize, szprec), prod))
warned = warning_at (loc, OPT_Walloc_size_larger_than_,
- "%Kproduct %<%E * %E%> of arguments %i and %i "
+ "product %<%E * %E%> of arguments %i and %i "
"exceeds maximum object size %E",
- exp, argrange[0][0], argrange[1][0],
+ argrange[0][0], argrange[1][0],
idx[0] + 1, idx[1] + 1,
maxobjsize);
@@ -1729,14 +1729,14 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
bool warned = false;
if (tree_int_cst_equal (bndrng[0], bndrng[1]))
warned = warning_at (loc, OPT_Wstringop_overread,
- "%K%qD specified bound %E "
+ "%qD specified bound %E "
"exceeds maximum object size %E",
- exp, fndecl, bndrng[0], maxobjsize);
+ fndecl, bndrng[0], maxobjsize);
else
warned = warning_at (loc, OPT_Wstringop_overread,
- "%K%qD specified bound [%E, %E] "
+ "%qD specified bound [%E, %E] "
"exceeds maximum object size %E",
- exp, fndecl, bndrng[0], bndrng[1],
+ fndecl, bndrng[0], bndrng[1],
maxobjsize);
if (warned)
suppress_warning (exp, OPT_Wstringop_overread);
@@ -2068,16 +2068,16 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp)
= access.second.array_as_string (ptrtype);
if (warning_at (loc, OPT_Wstringop_overflow_,
- "%Kbound argument %i value %s is "
+ "bound argument %i value %s is "
"negative for a variable length array "
"argument %i of type %s",
- exp, sizidx + 1, sizstr,
+ sizidx + 1, sizstr,
ptridx + 1, argtypestr.c_str ()))
arg_warned = OPT_Wstringop_overflow_;
}
else if (warning_at (loc, OPT_Wstringop_overflow_,
- "%Kargument %i value %s is negative",
- exp, sizidx + 1, sizstr))
+ "argument %i value %s is negative",
+ sizidx + 1, sizstr))
arg_warned = OPT_Wstringop_overflow_;
if (arg_warned != no_warning)
@@ -2124,20 +2124,19 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp)
= access.second.array_as_string (ptrtype);
if (warning_at (loc, OPT_Wnonnull,
- "%Kargument %i of variable length "
+ "argument %i of variable length "
"array %s is null but "
"the corresponding bound argument "
"%i value is %s",
- exp, sizidx + 1, argtypestr.c_str (),
+ sizidx + 1, argtypestr.c_str (),
ptridx + 1, sizstr))
arg_warned = OPT_Wnonnull;
}
else if (warning_at (loc, OPT_Wnonnull,
- "%Kargument %i is null but "
+ "argument %i is null but "
"the corresponding size argument "
"%i value is %s",
- exp, ptridx + 1, sizidx + 1,
- sizstr))
+ ptridx + 1, sizidx + 1, sizstr))
arg_warned = OPT_Wnonnull;
}
else if (access_size && access.second.static_p)
@@ -2145,10 +2144,9 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp)
/* Warn about null pointers for [static N] array arguments
but do not warn for ordinary (i.e., nonstatic) arrays. */
if (warning_at (loc, OPT_Wnonnull,
- "%Kargument %i to %<%T[static %E]%> "
+ "argument %i to %<%T[static %E]%> "
"is null where non-null expected",
- exp, ptridx + 1, argtype,
- access_size))
+ ptridx + 1, argtype, access_size))
arg_warned = OPT_Wnonnull;
}
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index e6df280..2af59fe 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1731,6 +1731,7 @@ loop_version (class loop *loop,
then_scale, else_scale);
copy_loop_info (loop, nloop);
+ set_loop_copy (loop, nloop);
/* loopify redirected latch_edge. Update its PENDING_STMTS. */
lv_flush_pending_stmts (latch_edge);
diff --git a/gcc/collect2.c b/gcc/collect2.c
index b08c6e7..07092c2 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -3040,15 +3040,49 @@ process_args (int *argcp, char **argv) {
static void
do_dsymutil (const char *output_file) {
- const char *dsymutil = DSYMUTIL + 1;
+ const char *dsymutil = 0;
struct pex_obj *pex;
- char **real_argv = XCNEWVEC (char *, 3);
+ char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
const char ** argv = CONST_CAST2 (const char **, char **,
real_argv);
+/* For cross-builds search the PATH using target-qualified name if we
+ have not already found a suitable dsymutil. In practice, all modern
+ versions of dsymutil handle all supported archs, however the approach
+ here is consistent with the way other installations work (and one can
+ always symlink a multitarget dsymutil with a target-specific name). */
+ const char *dsname = "dsymutil";
+#ifdef CROSS_DIRECTORY_STRUCTURE
+ const char *qname = concat (target_machine, "-", dsname, NULL);
+#else
+ const char *qname = dsname;
+#endif
+#ifdef DEFAULT_DSYMUTIL
+ /* Configured default takes priority. */
+ if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
+ dsymutil = DEFAULT_DSYMUTIL;
+ if (dsymutil == 0)
+#endif
+#ifdef DSYMUTIL
+ /* Followed by one supplied in the target header, somewhat like the
+ REAL_XX_NAME used elsewhere. */
+ dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
+ if (dsymutil == 0)
+ dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
+ if (dsymutil == 0)
+#endif
+ dsymutil = find_a_file (&cpath, dsname, X_OK);
+ if (dsymutil == 0)
+ dsymutil = find_a_file (&path, qname, X_OK);
argv[0] = dsymutil;
argv[1] = output_file;
- argv[2] = (char *) 0;
+ if (verbose)
+ {
+ argv[2] = "-v";
+ argv[3] = (char *) 0;
+ }
+ else
+ argv[2] = (char *) 0;
pex = collect_execute (dsymutil, real_argv, NULL, NULL,
PEX_LAST | PEX_SEARCH, false, NULL);
diff --git a/gcc/common.opt b/gcc/common.opt
index eaee74c..d9da113 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2084,6 +2084,10 @@ fmove-loop-invariants
Common Var(flag_move_loop_invariants) Optimization
Move loop invariant computations out of loops.
+fmove-loop-stores
+Common Var(flag_move_loop_stores) Optimization
+Move stores out of loops.
+
fdce
Common Var(flag_dce) Init(1) Optimization
Use the RTL dead code elimination pass.
@@ -2100,15 +2104,12 @@ fnon-call-exceptions
Common Var(flag_non_call_exceptions) Optimization
Support synchronous non-call exceptions.
-; -foffload=<targets> is documented
-; -foffload=<targets>=<options> is supported for backward compatibility
foffload=
Driver Joined MissingArgError(targets missing after %qs)
--foffload=<targets> Specify offloading targets
foffload-options=
Common Driver Joined MissingArgError(options or targets=options missing after %qs)
--foffload=<targets>=<options> Specify options for the offloading targets
+-foffload-options=<targets>=<options> Specify options for the offloading targets.
foffload-abi=
Common Joined RejectNegative Enum(offload_abi) Var(flag_offload_abi) Init(OFFLOAD_ABI_UNSET)
diff --git a/gcc/common/config/gcn/gcn-common.c b/gcc/common/config/gcn/gcn-common.c
index 305c310..695eb46 100644
--- a/gcc/common/config/gcn/gcn-common.c
+++ b/gcc/common/config/gcn/gcn-common.c
@@ -27,7 +27,7 @@
/* Set default optimization options. */
static const struct default_options gcn_option_optimization_table[] =
{
- { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 0230bb8..f3e94f7 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -591,6 +591,8 @@ i[34567]86-*-*)
exit 1
fi
;;
+x86_64-*-darwin*)
+ ;;
x86_64-*-*)
case ${with_abi} in
"")
@@ -1837,7 +1839,7 @@ hppa[12]*-*-hpux11*)
dwarf2=no
fi
;;
-i[34567]86-*-darwin1[89]*)
+i[34567]86-*-darwin1[89]* | i[34567]86-*-darwin2[0-9]*)
echo "Error: 32bit target is not supported after Darwin17" 1>&2
;;
i[34567]86-*-darwin*)
@@ -1845,17 +1847,19 @@ i[34567]86-*-darwin*)
# Baseline choice for a machine that allows m64 support.
with_cpu=${with_cpu:-core2}
tmake_file="${tmake_file} ${cpu_type}/t-darwin32-biarch t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin32-biarch.h"
+ tm_file="${cpu_type}/darwin32-biarch.h ${tm_file} "
;;
x86_64-*-darwin1[89]* | x86_64-*-darwin2[01]*)
# Only 64b from now
+ tm_defines="${tm_defines} TARGET_64BIT_DEFAULT=(OPTION_MASK_ISA_64BIT|OPTION_MASK_ABI_64)"
+ tm_defines="${tm_defines} TARGET_BI_ARCH=0"
with_cpu=${with_cpu:-core2}
tmake_file="${tmake_file} t-slibgcc"
;;
x86_64-*-darwin*)
with_cpu=${with_cpu:-core2}
tmake_file="${tmake_file} ${cpu_type}/t-darwin64-biarch t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin64-biarch.h"
+ tm_file="${cpu_type}/darwin64-biarch.h ${tm_file} "
;;
i[34567]86-*-elfiamcu)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/iamcu.h"
diff --git a/gcc/config.in b/gcc/config.in
index 18e6271..2abac53 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -55,6 +55,12 @@
#endif
+/* Define to enable the use of a default debug linker. */
+#ifndef USED_FOR_TARGET
+#undef DEFAULT_DSYMUTIL
+#endif
+
+
/* Define to enable the use of a default linker. */
#ifndef USED_FOR_TARGET
#undef DEFAULT_LINKER
@@ -94,6 +100,12 @@
#endif
+/* Define to the dsymutil version. */
+#ifndef USED_FOR_TARGET
+#undef DSYMUTIL_VERSION
+#endif
+
+
/* Define 0/1 if static analyzer feature is enabled. */
#ifndef USED_FOR_TARGET
#undef ENABLE_ANALYZER
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 3cab3ec..9ed4b72 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -1598,8 +1598,9 @@ constant_arg:
if (!(*insn_data[icode].operand[opc].predicate)
(op[opc], mode))
{
- error ("%Kargument %d must be a constant immediate",
- exp, opc + 1 - have_retval);
+ error_at (EXPR_LOCATION (exp),
+ "argument %d must be a constant immediate",
+ opc + 1 - have_retval);
return const0_rtx;
}
break;
@@ -1669,10 +1670,13 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
/ UINTVAL (elementsize),
exp);
else
- error ("%Klane index must be a constant immediate", exp);
+ error_at (EXPR_LOCATION (exp),
+ "lane index must be a constant immediate");
}
else
- error ("%Ktotal size and element size must be a non-zero constant immediate", exp);
+ error_at (EXPR_LOCATION (exp),
+ "total size and element size must be a non-zero "
+ "constant immediate");
/* Don't generate any RTL. */
return const0_rtx;
}
@@ -1828,7 +1832,8 @@ aarch64_expand_fcmla_builtin (tree exp, rtx target, int fcode)
/* Validate that the lane index is a constant. */
if (!CONST_INT_P (lane_idx))
{
- error ("%Kargument %d must be a constant immediate", exp, 4);
+ error_at (EXPR_LOCATION (exp),
+ "argument %d must be a constant immediate", 4);
return const0_rtx;
}
@@ -1917,7 +1922,8 @@ aarch64_expand_builtin_tme (int fcode, tree exp, rtx target)
emit_insn (GEN_FCN (CODE_FOR_tcancel) (op0));
else
{
- error ("%Kargument must be a 16-bit constant immediate", exp);
+ error_at (EXPR_LOCATION (exp),
+ "argument must be a 16-bit constant immediate");
return const0_rtx;
}
}
@@ -2006,8 +2012,9 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
pat = GEN_FCN (icode) (target, op0, const0_rtx, op1);
break;
}
- error ("%Kargument %d must be a constant immediate "
- "in range [0,15]", exp, 2);
+ error_at (EXPR_LOCATION (exp),
+ "argument %d must be a constant immediate "
+ "in range [0,15]", 2);
return const0_rtx;
}
else
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 2753c85..f5b25a7 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -20128,7 +20128,8 @@ aarch64_simd_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
if (lane < low || lane >= high)
{
if (exp)
- error ("%Klane %wd out of range %wd - %wd", exp, lane, low, high - 1);
+ error_at (EXPR_LOCATION (exp), "lane %wd out of range %wd - %wd",
+ lane, low, high - 1);
else
error ("lane %wd out of range %wd - %wd", lane, low, high - 1);
}
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index fa0fb0b..3a9ff8f 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -3092,26 +3092,30 @@ constant_arg:
unsigned int cp_bit = (CONST_INT_P (op[argc])
? UINTVAL (op[argc]) : -1);
if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC))
- error ("%Kcoprocessor %d is not enabled "
- "with +cdecp%d", exp, cp_bit, cp_bit);
+ error_at (EXPR_LOCATION (exp),
+ "coprocessor %d is not enabled "
+ "with +cdecp%d", cp_bit, cp_bit);
else
- error ("%Kcoproc must be a constant immediate in "
- "range [0-%d] enabled with +cdecp<N>", exp,
- ARM_CDE_CONST_COPROC);
+ error_at (EXPR_LOCATION (exp),
+ "coproc must be a constant immediate in "
+ "range [0-%d] enabled with +cdecp<N>",
+ ARM_CDE_CONST_COPROC);
}
else
/* Here we mention the builtin name to follow the same
format that the C/C++ frontends use for referencing
a given argument index. */
- error ("%Kargument %d to %qE must be a constant immediate "
- "in range [0-%d]", exp, argc + 1,
+ error_at (EXPR_LOCATION (exp),
+ "argument %d to %qE must be a constant "
+ "immediate in range [0-%d]", argc + 1,
arm_builtin_decls[fcode],
cde_builtin_data[fcode -
ARM_BUILTIN_CDE_PATTERN_START].imm_max);
}
else
- error ("%Kargument %d must be a constant immediate",
- exp, argc + 1);
+ error_at (EXPR_LOCATION (exp),
+ "argument %d must be a constant immediate",
+ argc + 1);
/* We have failed to expand the pattern, and are safely
in to invalid code. But the mid-end will still try to
build an assignment for this node while it expands,
@@ -3328,11 +3332,13 @@ arm_expand_acle_builtin (int fcode, tree exp, rtx target)
if (CONST_INT_P (sat_imm))
{
if (!IN_RANGE (sat_imm, min_sat, max_sat))
- error ("%Ksaturation bit range must be in the range [%wd, %wd]",
- exp, UINTVAL (min_sat), UINTVAL (max_sat));
+ error_at (EXPR_LOCATION (exp),
+ "saturation bit range must be in the range [%wd, %wd]",
+ UINTVAL (min_sat), UINTVAL (max_sat));
}
else
- error ("%Ksaturation bit range must be a constant immediate", exp);
+ error_at (EXPR_LOCATION (exp),
+ "saturation bit range must be a constant immediate");
/* Don't generate any RTL. */
return const0_rtx;
}
@@ -3455,7 +3461,8 @@ arm_expand_builtin (tree exp,
if (CONST_INT_P (lane_idx))
neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
else
- error ("%Klane index must be a constant immediate", exp);
+ error_at (EXPR_LOCATION (exp),
+ "lane index must be a constant immediate");
/* Don't generate any RTL. */
return const0_rtx;
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 7b37e1b..de37c90 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13244,8 +13244,8 @@ bounds_check (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
if (lane < low || lane >= high)
{
if (exp)
- error ("%K%s %wd out of range %wd - %wd",
- exp, desc, lane, low, high - 1);
+ error_at (EXPR_LOCATION (exp),
+ "%s %wd out of range %wd - %wd", desc, lane, low, high - 1);
else
error ("%s %wd out of range %wd - %wd", desc, lane, low, high - 1);
}
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index 7a800062..f42a15f 100644
--- a/gcc/config/arm/arm_neon.h
+++ b/gcc/config/arm/arm_neon.h
@@ -2867,60 +2867,189 @@ vcltq_u32 (uint32x4_t __a, uint32x4_t __b)
return (__a < __b);
}
+__extension__ extern __inline int8x8_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabs_s8 (int8x8_t __a)
+{
+ return (int8x8_t)__builtin_neon_vabsv8qi (__a);
+}
+
+__extension__ extern __inline int16x4_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabs_s16 (int16x4_t __a)
+{
+ return (int16x4_t)__builtin_neon_vabsv4hi (__a);
+}
+
+__extension__ extern __inline int32x2_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabs_s32 (int32x2_t __a)
+{
+ return (int32x2_t)__builtin_neon_vabsv2si (__a);
+}
+
+__extension__ extern __inline float32x2_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabs_f32 (float32x2_t __a)
+{
+ return (float32x2_t)__builtin_neon_vabsv2sf (__a);
+}
+
+__extension__ extern __inline int8x16_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabsq_s8 (int8x16_t __a)
+{
+ return (int8x16_t)__builtin_neon_vabsv16qi (__a);
+}
+
+__extension__ extern __inline int16x8_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabsq_s16 (int16x8_t __a)
+{
+ return (int16x8_t)__builtin_neon_vabsv8hi (__a);
+}
+
+__extension__ extern __inline int32x4_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabsq_s32 (int32x4_t __a)
+{
+ return (int32x4_t)__builtin_neon_vabsv4si (__a);
+}
+
+__extension__ extern __inline float32x4_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vabsq_f32 (float32x4_t __a)
+{
+ return (float32x4_t)__builtin_neon_vabsv4sf (__a);
+}
+
+__extension__ extern __inline int8x8_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabs_s8 (int8x8_t __a)
+{
+ return (int8x8_t)__builtin_neon_vqabsv8qi (__a);
+}
+
+__extension__ extern __inline int16x4_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabs_s16 (int16x4_t __a)
+{
+ return (int16x4_t)__builtin_neon_vqabsv4hi (__a);
+}
+
+__extension__ extern __inline int32x2_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabs_s32 (int32x2_t __a)
+{
+ return (int32x2_t)__builtin_neon_vqabsv2si (__a);
+}
+
+__extension__ extern __inline int8x16_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabsq_s8 (int8x16_t __a)
+{
+ return (int8x16_t)__builtin_neon_vqabsv16qi (__a);
+}
+
+__extension__ extern __inline int16x8_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabsq_s16 (int16x8_t __a)
+{
+ return (int16x8_t)__builtin_neon_vqabsv8hi (__a);
+}
+
+__extension__ extern __inline int32x4_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vqabsq_s32 (int32x4_t __a)
+{
+ return (int32x4_t)__builtin_neon_vqabsv4si (__a);
+}
__extension__ extern __inline uint32x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcage_f32 (float32x2_t __a, float32x2_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x2_t) (vabs_f32 (__a) >= vabs_f32 (__b));
+#else
return (uint32x2_t)__builtin_neon_vcagev2sf (__a, __b);
+#endif
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcageq_f32 (float32x4_t __a, float32x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x4_t) (vabsq_f32 (__a) >= vabsq_f32 (__b));
+#else
return (uint32x4_t)__builtin_neon_vcagev4sf (__a, __b);
+#endif
}
__extension__ extern __inline uint32x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcale_f32 (float32x2_t __a, float32x2_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x2_t) (vabs_f32 (__a) <= vabs_f32 (__b));
+#else
return (uint32x2_t)__builtin_neon_vcagev2sf (__b, __a);
+#endif
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcaleq_f32 (float32x4_t __a, float32x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x4_t) (vabsq_f32 (__a) <= vabsq_f32 (__b));
+#else
return (uint32x4_t)__builtin_neon_vcagev4sf (__b, __a);
+#endif
}
__extension__ extern __inline uint32x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcagt_f32 (float32x2_t __a, float32x2_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x2_t) (vabs_f32 (__a) > vabs_f32 (__b));
+#else
return (uint32x2_t)__builtin_neon_vcagtv2sf (__a, __b);
+#endif
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcagtq_f32 (float32x4_t __a, float32x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x4_t) (vabsq_f32 (__a) > vabsq_f32 (__b));
+#else
return (uint32x4_t)__builtin_neon_vcagtv4sf (__a, __b);
+#endif
}
__extension__ extern __inline uint32x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcalt_f32 (float32x2_t __a, float32x2_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x2_t) (vabs_f32 (__a) < vabs_f32 (__b));
+#else
return (uint32x2_t)__builtin_neon_vcagtv2sf (__b, __a);
+#endif
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcaltq_f32 (float32x4_t __a, float32x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint32x4_t) (vabsq_f32 (__a) < vabsq_f32 (__b));
+#else
return (uint32x4_t)__builtin_neon_vcagtv4sf (__b, __a);
+#endif
}
__extension__ extern __inline uint8x8_t
@@ -5622,104 +5751,6 @@ vsliq_n_p16 (poly16x8_t __a, poly16x8_t __b, const int __c)
__extension__ extern __inline int8x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s8 (int8x8_t __a)
-{
- return (int8x8_t)__builtin_neon_vabsv8qi (__a);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s16 (int16x4_t __a)
-{
- return (int16x4_t)__builtin_neon_vabsv4hi (__a);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s32 (int32x2_t __a)
-{
- return (int32x2_t)__builtin_neon_vabsv2si (__a);
-}
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_f32 (float32x2_t __a)
-{
- return (float32x2_t)__builtin_neon_vabsv2sf (__a);
-}
-
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s8 (int8x16_t __a)
-{
- return (int8x16_t)__builtin_neon_vabsv16qi (__a);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s16 (int16x8_t __a)
-{
- return (int16x8_t)__builtin_neon_vabsv8hi (__a);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s32 (int32x4_t __a)
-{
- return (int32x4_t)__builtin_neon_vabsv4si (__a);
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_f32 (float32x4_t __a)
-{
- return (float32x4_t)__builtin_neon_vabsv4sf (__a);
-}
-
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabs_s8 (int8x8_t __a)
-{
- return (int8x8_t)__builtin_neon_vqabsv8qi (__a);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabs_s16 (int16x4_t __a)
-{
- return (int16x4_t)__builtin_neon_vqabsv4hi (__a);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabs_s32 (int32x2_t __a)
-{
- return (int32x2_t)__builtin_neon_vqabsv2si (__a);
-}
-
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabsq_s8 (int8x16_t __a)
-{
- return (int8x16_t)__builtin_neon_vqabsv16qi (__a);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabsq_s16 (int16x8_t __a)
-{
- return (int16x8_t)__builtin_neon_vqabsv8hi (__a);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqabsq_s32 (int32x4_t __a)
-{
- return (int32x4_t)__builtin_neon_vqabsv4si (__a);
-}
-
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vneg_s8 (int8x8_t __a)
{
return -__a;
@@ -17147,56 +17178,88 @@ __extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcage_f16 (float16x4_t __a, float16x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x4_t) (vabs_f16 (__a) >= vabs_f16 (__b));
+#else
return (uint16x4_t)__builtin_neon_vcagev4hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcageq_f16 (float16x8_t __a, float16x8_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x8_t) (vabsq_f16 (__a) >= vabsq_f16 (__b));
+#else
return (uint16x8_t)__builtin_neon_vcagev8hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcagt_f16 (float16x4_t __a, float16x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x4_t) (vabs_f16 (__a) > vabs_f16 (__b));
+#else
return (uint16x4_t)__builtin_neon_vcagtv4hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcagtq_f16 (float16x8_t __a, float16x8_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x8_t) (vabsq_f16 (__a) > vabsq_f16 (__b));
+#else
return (uint16x8_t)__builtin_neon_vcagtv8hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcale_f16 (float16x4_t __a, float16x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x4_t) (vabs_f16 (__a) <= vabs_f16 (__b));
+#else
return (uint16x4_t)__builtin_neon_vcalev4hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcaleq_f16 (float16x8_t __a, float16x8_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x8_t) (vabsq_f16 (__a) <= vabsq_f16 (__b));
+#else
return (uint16x8_t)__builtin_neon_vcalev8hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcalt_f16 (float16x4_t __a, float16x4_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x4_t) (vabs_f16 (__a) < vabs_f16 (__b));
+#else
return (uint16x4_t)__builtin_neon_vcaltv4hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcaltq_f16 (float16x8_t __a, float16x8_t __b)
{
+#ifdef __FAST_MATH__
+ return (uint16x8_t) (vabsq_f16 (__a) < vabsq_f16 (__b));
+#else
return (uint16x8_t)__builtin_neon_vcaltv8hf (__a, __b);
+#endif
}
__extension__ extern __inline uint16x4_t
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 81cc8d3..64365e0 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -458,15 +458,6 @@
[(set_attr "type" "neon_store1_one_lane_q,neon_to_gp_q")]
)
-(define_expand "vec_init<mode><V_elem_l>"
- [(match_operand:VDQ 0 "s_register_operand")
- (match_operand 1 "" "")]
- "TARGET_NEON || TARGET_HAVE_MVE"
-{
- neon_expand_vector_init (operands[0], operands[1]);
- DONE;
-})
-
;; Doubleword and quadword arithmetic.
;; NOTE: some other instructions also support 64-bit integer
diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md
index f90afa4..68de4f0 100644
--- a/gcc/config/arm/vec-common.md
+++ b/gcc/config/arm/vec-common.md
@@ -702,3 +702,12 @@
DONE;
}
)
+
+(define_expand "vec_init<mode><V_elem_l>"
+ [(match_operand:VDQX 0 "s_register_operand")
+ (match_operand 1 "" "")]
+ "TARGET_NEON || (TARGET_HAVE_MVE && VALID_MVE_MODE (<MODE>mode))"
+{
+ neon_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index d2b2c14..20d6b1e 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -240,8 +240,6 @@ extern GTY(()) int darwin_ms_struct;
DARWIN_NOCOMPACT_UNWIND \
"}}}}}}} %<pie %<no-pie %<rdynamic %<X "
-#define DSYMUTIL "\ndsymutil"
-
/* Spec that controls whether the debug linker is run automatically for
a link step. This needs to be done if there is a source file on the
command line which will result in a temporary object (and debug is
@@ -250,10 +248,10 @@ extern GTY(()) int darwin_ms_struct;
#define DSYMUTIL_SPEC \
"%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%{v} \
- %{g*:%{!gstabs*:%{%:debug-level-gt(0): -idsym}}}\
+ %{g*:%{!gctf:%{!gbtf:%{!gstabs*:%{%:debug-level-gt(0): -idsym}}}}}\
%{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm|.s|.f|.f90|\
.f95|.f03|.f77|.for|.F|.F90|.F95|.F03: \
- %{g*:%{!gstabs*:%{%:debug-level-gt(0): -dsym}}}}}}}}}}}"
+ %{g*:%{!gctf:%{!gbtf:%{!gstabs*:%{%:debug-level-gt(0): -dsym}}}}}}}}}}}}}"
#define LINK_COMMAND_SPEC LINK_COMMAND_SPEC_A DSYMUTIL_SPEC
@@ -1115,4 +1113,10 @@ extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **);
# endif
#endif
+/* CTF and BTF support. */
+#undef CTF_INFO_SECTION_NAME
+#define CTF_INFO_SECTION_NAME "__CTF_BTF,__ctf,regular,debug"
+#undef BTF_INFO_SECTION_NAME
+#define BTF_INFO_SECTION_NAME "__CTF_BTF,__btf,regular,debug"
+
#endif /* CONFIG_DARWIN_H */
diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h
index 8d79d73..29d4425 100644
--- a/gcc/config/frv/frv-protos.h
+++ b/gcc/config/frv/frv-protos.h
@@ -89,73 +89,73 @@ extern int frv_adjust_field_align (tree, int);
#endif
#ifdef RTX_CODE
-extern int integer_register_operand (rtx, machine_mode);
-extern int frv_load_operand (rtx, machine_mode);
-extern int gpr_or_fpr_operand (rtx, machine_mode);
-extern int gpr_no_subreg_operand (rtx, machine_mode);
+extern bool integer_register_operand (rtx, machine_mode);
+extern bool frv_load_operand (rtx, machine_mode);
+extern bool gpr_or_fpr_operand (rtx, machine_mode);
+extern bool gpr_no_subreg_operand (rtx, machine_mode);
extern int gpr_or_int6_operand (rtx, machine_mode);
-extern int fpr_or_int6_operand (rtx, machine_mode);
-extern int gpr_or_int_operand (rtx, machine_mode);
-extern int gpr_or_int12_operand (rtx, machine_mode);
-extern int gpr_fpr_or_int12_operand (rtx, machine_mode);
-extern int gpr_or_int10_operand (rtx, machine_mode);
-extern int move_source_operand (rtx, machine_mode);
-extern int move_destination_operand (rtx, machine_mode);
-extern int condexec_source_operand (rtx, machine_mode);
-extern int condexec_dest_operand (rtx, machine_mode);
-extern int lr_operand (rtx, machine_mode);
-extern int gpr_or_memory_operand (rtx, machine_mode);
-extern int fpr_or_memory_operand (rtx, machine_mode);
-extern int reg_or_0_operand (rtx, machine_mode);
-extern int fcc_operand (rtx, machine_mode);
-extern int icc_operand (rtx, machine_mode);
-extern int cc_operand (rtx, machine_mode);
-extern int fcr_operand (rtx, machine_mode);
-extern int icr_operand (rtx, machine_mode);
-extern int cr_operand (rtx, machine_mode);
-extern int call_operand (rtx, machine_mode);
-extern int fpr_operand (rtx, machine_mode);
-extern int even_reg_operand (rtx, machine_mode);
-extern int odd_reg_operand (rtx, machine_mode);
-extern int even_gpr_operand (rtx, machine_mode);
-extern int odd_gpr_operand (rtx, machine_mode);
-extern int quad_fpr_operand (rtx, machine_mode);
-extern int even_fpr_operand (rtx, machine_mode);
-extern int odd_fpr_operand (rtx, machine_mode);
-extern int dbl_memory_one_insn_operand (rtx, machine_mode);
-extern int dbl_memory_two_insn_operand (rtx, machine_mode);
-extern int int12_operand (rtx, machine_mode);
-extern int int6_operand (rtx, machine_mode);
-extern int int5_operand (rtx, machine_mode);
-extern int uint5_operand (rtx, machine_mode);
-extern int uint4_operand (rtx, machine_mode);
-extern int uint1_operand (rtx, machine_mode);
-extern int int_2word_operand (rtx, machine_mode);
+extern bool fpr_or_int6_operand (rtx, machine_mode);
+extern bool gpr_or_int_operand (rtx, machine_mode);
+extern bool gpr_or_int12_operand (rtx, machine_mode);
+extern bool gpr_fpr_or_int12_operand (rtx, machine_mode);
+extern bool gpr_or_int10_operand (rtx, machine_mode);
+extern bool move_source_operand (rtx, machine_mode);
+extern bool move_destination_operand (rtx, machine_mode);
+extern bool condexec_source_operand (rtx, machine_mode);
+extern bool condexec_dest_operand (rtx, machine_mode);
+extern bool lr_operand (rtx, machine_mode);
+extern bool gpr_or_memory_operand (rtx, machine_mode);
+extern bool fpr_or_memory_operand (rtx, machine_mode);
+extern bool reg_or_0_operand (rtx, machine_mode);
+extern bool fcc_operand (rtx, machine_mode);
+extern bool icc_operand (rtx, machine_mode);
+extern bool cc_operand (rtx, machine_mode);
+extern bool fcr_operand (rtx, machine_mode);
+extern bool icr_operand (rtx, machine_mode);
+extern bool cr_operand (rtx, machine_mode);
+extern bool call_operand (rtx, machine_mode);
+extern bool fpr_operand (rtx, machine_mode);
+extern bool even_reg_operand (rtx, machine_mode);
+extern bool odd_reg_operand (rtx, machine_mode);
+extern bool even_gpr_operand (rtx, machine_mode);
+extern bool odd_gpr_operand (rtx, machine_mode);
+extern bool quad_fpr_operand (rtx, machine_mode);
+extern bool even_fpr_operand (rtx, machine_mode);
+extern bool odd_fpr_operand (rtx, machine_mode);
+extern bool dbl_memory_one_insn_operand (rtx, machine_mode);
+extern bool dbl_memory_two_insn_operand (rtx, machine_mode);
+extern bool int12_operand (rtx, machine_mode);
+extern bool int6_operand (rtx, machine_mode);
+extern bool int5_operand (rtx, machine_mode);
+extern bool uint5_operand (rtx, machine_mode);
+extern bool uint4_operand (rtx, machine_mode);
+extern bool uint1_operand (rtx, machine_mode);
+extern bool int_2word_operand (rtx, machine_mode);
extern int pic_register_operand (rtx, machine_mode);
extern int pic_symbolic_operand (rtx, machine_mode);
extern int small_data_register_operand (rtx, machine_mode);
extern int small_data_symbolic_operand (rtx, machine_mode);
-extern int upper_int16_operand (rtx, machine_mode);
-extern int uint16_operand (rtx, machine_mode);
-extern int symbolic_operand (rtx, machine_mode);
-extern int relational_operator (rtx, machine_mode);
+extern bool upper_int16_operand (rtx, machine_mode);
+extern bool uint16_operand (rtx, machine_mode);
+extern bool symbolic_operand (rtx, machine_mode);
+extern bool relational_operator (rtx, machine_mode);
extern int signed_relational_operator (rtx, machine_mode);
extern int unsigned_relational_operator (rtx, machine_mode);
-extern int float_relational_operator (rtx, machine_mode);
-extern int ccr_eqne_operator (rtx, machine_mode);
-extern int minmax_operator (rtx, machine_mode);
-extern int condexec_si_binary_operator (rtx, machine_mode);
-extern int condexec_si_media_operator (rtx, machine_mode);
-extern int condexec_si_divide_operator (rtx, machine_mode);
-extern int condexec_si_unary_operator (rtx, machine_mode);
-extern int condexec_sf_conv_operator (rtx, machine_mode);
-extern int condexec_sf_add_operator (rtx, machine_mode);
+extern bool float_relational_operator (rtx, machine_mode);
+extern bool ccr_eqne_operator (rtx, machine_mode);
+extern bool minmax_operator (rtx, machine_mode);
+extern bool condexec_si_binary_operator (rtx, machine_mode);
+extern bool condexec_si_media_operator (rtx, machine_mode);
+extern bool condexec_si_divide_operator (rtx, machine_mode);
+extern bool condexec_si_unary_operator (rtx, machine_mode);
+extern bool condexec_sf_conv_operator (rtx, machine_mode);
+extern bool condexec_sf_add_operator (rtx, machine_mode);
extern int condexec_memory_operand (rtx, machine_mode);
-extern int intop_compare_operator (rtx, machine_mode);
-extern int acc_operand (rtx, machine_mode);
-extern int even_acc_operand (rtx, machine_mode);
-extern int quad_acc_operand (rtx, machine_mode);
-extern int accg_operand (rtx, machine_mode);
+extern bool intop_compare_operator (rtx, machine_mode);
+extern bool acc_operand (rtx, machine_mode);
+extern bool even_acc_operand (rtx, machine_mode);
+extern bool quad_acc_operand (rtx, machine_mode);
+extern bool accg_operand (rtx, machine_mode);
extern rtx frv_matching_accg_for_acc (rtx);
extern void frv_expand_fdpic_call (rtx *, bool, bool);
extern rtx frv_gen_GPsym2reg (rtx, rtx);
diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index aa9d455..6d02a4a 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -50,6 +50,7 @@
#include "varasm.h"
#include "intl.h"
#include "rtl-iter.h"
+#include "dwarf2.h"
/* This file should be included last. */
#include "target-def.h"
@@ -1497,6 +1498,32 @@ gcn_addr_space_convert (rtx op, tree from_type, tree to_type)
gcc_unreachable ();
}
+/* Implement TARGET_ADDR_SPACE_DEBUG.
+
+ Return the dwarf address space class for each hardware address space. */
+
+static int
+gcn_addr_space_debug (addr_space_t as)
+{
+ switch (as)
+ {
+ case ADDR_SPACE_DEFAULT:
+ case ADDR_SPACE_FLAT:
+ case ADDR_SPACE_SCALAR_FLAT:
+ case ADDR_SPACE_FLAT_SCRATCH:
+ return DW_ADDR_none;
+ case ADDR_SPACE_GLOBAL:
+ return 1; // DW_ADDR_LLVM_global
+ case ADDR_SPACE_LDS:
+ return 3; // DW_ADDR_LLVM_group
+ case ADDR_SPACE_SCRATCH:
+ return 4; // DW_ADDR_LLVM_private
+ case ADDR_SPACE_GDS:
+ return 0x8000; // DW_ADDR_AMDGPU_region
+ }
+ gcc_unreachable ();
+}
+
/* Implement REGNO_MODE_CODE_OK_FOR_BASE_P via gcn.h
@@ -2649,6 +2676,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
rtx as = gen_rtx_CONST_INT (VOIDmode, STACK_ADDR_SPACE);
HOST_WIDE_INT exec_set = 0;
int offreg_set = 0;
+ auto_vec<int> saved_sgprs;
start_sequence ();
@@ -2665,7 +2693,10 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
int lane = saved_scalars % 64;
if (prologue)
- emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
+ {
+ emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
+ saved_sgprs.safe_push (regno);
+ }
else
emit_insn (gen_vec_extractv64sisi (reg, vreg, GEN_INT (lane)));
@@ -2698,7 +2729,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
gcn_gen_undef (V64SImode), exec));
/* Move vectors. */
- for (regno = FIRST_VGPR_REG, offset = offsets->pretend_size;
+ for (regno = FIRST_VGPR_REG, offset = 0;
regno < FIRST_PSEUDO_REGISTER; regno++)
if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
|| (regno == VGPR_REGNO (6) && saved_scalars > 0)
@@ -2719,8 +2750,67 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
}
if (prologue)
- emit_insn (gen_scatterv64si_insn_1offset_exec (vsp, const0_rtx, reg,
- as, const0_rtx, exec));
+ {
+ rtx insn = emit_insn (gen_scatterv64si_insn_1offset_exec
+ (vsp, const0_rtx, reg, as, const0_rtx,
+ exec));
+
+ /* Add CFI metadata. */
+ rtx note;
+ if (regno == VGPR_REGNO (6) || regno == VGPR_REGNO (7))
+ {
+ int start = (regno == VGPR_REGNO (7) ? 64 : 0);
+ int count = MIN (saved_scalars - start, 64);
+ int add_lr = (regno == VGPR_REGNO (6)
+ && df_regs_ever_live_p (LINK_REGNUM));
+ int lrdest = -1;
+ rtvec seq = rtvec_alloc (count + add_lr);
+
+ /* Add an REG_FRAME_RELATED_EXPR entry for each scalar
+ register that was saved in this batch. */
+ for (int idx = 0; idx < count; idx++)
+ {
+ int stackaddr = offset + idx * 4;
+ rtx dest = gen_rtx_MEM (SImode,
+ gen_rtx_PLUS
+ (DImode, sp,
+ GEN_INT (stackaddr)));
+ rtx src = gen_rtx_REG (SImode, saved_sgprs[start + idx]);
+ rtx set = gen_rtx_SET (dest, src);
+ RTX_FRAME_RELATED_P (set) = 1;
+ RTVEC_ELT (seq, idx) = set;
+
+ if (saved_sgprs[start + idx] == LINK_REGNUM)
+ lrdest = stackaddr;
+ }
+
+ /* Add an additional expression for DWARF_LINK_REGISTER if
+ LINK_REGNUM was saved. */
+ if (lrdest != -1)
+ {
+ rtx dest = gen_rtx_MEM (DImode,
+ gen_rtx_PLUS
+ (DImode, sp,
+ GEN_INT (lrdest)));
+ rtx src = gen_rtx_REG (DImode, DWARF_LINK_REGISTER);
+ rtx set = gen_rtx_SET (dest, src);
+ RTX_FRAME_RELATED_P (set) = 1;
+ RTVEC_ELT (seq, count) = set;
+ }
+
+ note = gen_rtx_SEQUENCE (VOIDmode, seq);
+ }
+ else
+ {
+ rtx dest = gen_rtx_MEM (V64SImode,
+ gen_rtx_PLUS (DImode, sp,
+ GEN_INT (offset)));
+ rtx src = gen_rtx_REG (V64SImode, regno);
+ note = gen_rtx_SET (dest, src);
+ }
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
+ }
else
emit_insn (gen_gatherv64si_insn_1offset_exec
(reg, vsp, const0_rtx, as, const0_rtx,
@@ -2837,10 +2927,14 @@ gcn_expand_prologue ()
rtx adjustment = gen_int_mode (sp_adjust, SImode);
rtx insn = emit_insn (gen_addsi3_scalar_carry (sp_lo, sp_lo,
adjustment, scc));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (sp,
- gen_rtx_PLUS (DImode, sp, adjustment)));
+ if (!offsets->need_frame_pointer)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (sp,
+ gen_rtx_PLUS (DImode, sp,
+ adjustment)));
+ }
emit_insn (gen_addcsi3_scalar_zero (sp_hi, sp_hi, scc));
}
@@ -2854,25 +2948,24 @@ gcn_expand_prologue ()
rtx adjustment = gen_int_mode (fp_adjust, SImode);
rtx insn = emit_insn (gen_addsi3_scalar_carry(fp_lo, sp_lo,
adjustment, scc));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (fp,
- gen_rtx_PLUS (DImode, sp, adjustment)));
emit_insn (gen_addcsi3_scalar (fp_hi, sp_hi,
(fp_adjust < 0 ? GEN_INT (-1)
: const0_rtx),
scc, scc));
+
+ /* Set the CFA to the entry stack address, as an offset from the
+ frame pointer. This is preferred because the frame pointer is
+ saved in each frame, whereas the stack pointer is not. */
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ gen_rtx_PLUS (DImode, fp,
+ GEN_INT (-(offsets->pretend_size
+ + offsets->callee_saves))));
}
rtx_insn *seq = get_insns ();
end_sequence ();
- /* FIXME: Prologue insns should have this flag set for debug output, etc.
- but it causes issues for now.
- for (insn = seq; insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- RTX_FRAME_RELATED_P (insn) = 1;*/
-
emit_insn (seq);
}
else
@@ -2948,6 +3041,16 @@ gcn_expand_prologue ()
gen_rtx_SET (sp, gen_rtx_PLUS (DImode, sp,
dbg_adjustment)));
+ if (offsets->need_frame_pointer)
+ {
+ /* Set the CFA to the entry stack address, as an offset from the
+ frame pointer. This is necessary when alloca is used, and
+ harmless otherwise. */
+ rtx neg_adjust = gen_int_mode (-offsets->callee_saves, DImode);
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ gen_rtx_PLUS (DImode, fp, neg_adjust));
+ }
+
/* Make sure the flat scratch reg doesn't get optimised away. */
emit_insn (gen_prologue_use (gen_rtx_REG (DImode, FLAT_SCRATCH_REG)));
}
@@ -3051,6 +3154,23 @@ gcn_expand_epilogue (void)
emit_jump_insn (gen_gcn_return ());
}
+/* Implement TARGET_FRAME_POINTER_REQUIRED.
+
+ Return true if the frame pointer should not be eliminated. */
+
+bool
+gcn_frame_pointer_rqd (void)
+{
+ /* GDB needs the frame pointer in order to unwind properly,
+ but that's not important for the entry point, unless alloca is used.
+ It's not important for code execution, so we should repect the
+ -fomit-frame-pointer flag. */
+ return (!flag_omit_frame_pointer
+ && cfun
+ && (cfun->calls_alloca
+ || (cfun->machine && cfun->machine->normal_function)));
+}
+
/* Implement TARGET_CAN_ELIMINATE.
Return true if the compiler is allowed to try to replace register number
@@ -3224,8 +3344,7 @@ gcn_cannot_copy_insn_p (rtx_insn *insn)
static enum unwind_info_type
gcn_debug_unwind_info ()
{
- /* No support for debug info, yet. */
- return UI_NONE;
+ return UI_DWARF2;
}
/* Determine if there is a suitable hardware conversion instruction.
@@ -6251,6 +6370,8 @@ gcn_dwarf_register_number (unsigned int regno)
return 768; */
else if (regno == SCC_REG)
return 128;
+ else if (regno == DWARF_LINK_REGISTER)
+ return 16;
else if (SGPR_REGNO_P (regno))
{
if (regno - FIRST_SGPR_REG < 64)
@@ -6280,8 +6401,12 @@ gcn_dwarf_register_span (rtx rtl)
if (GET_MODE_SIZE (mode) != 8)
return NULL_RTX;
- rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
unsigned regno = REGNO (rtl);
+
+ if (regno == DWARF_LINK_REGISTER)
+ return NULL_RTX;
+
+ rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
@@ -6293,6 +6418,8 @@ gcn_dwarf_register_span (rtx rtl)
#undef TARGET_ADDR_SPACE_ADDRESS_MODE
#define TARGET_ADDR_SPACE_ADDRESS_MODE gcn_addr_space_address_mode
+#undef TARGET_ADDR_SPACE_DEBUG
+#define TARGET_ADDR_SPACE_DEBUG gcn_addr_space_debug
#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
gcn_addr_space_legitimate_address_p
@@ -6342,6 +6469,8 @@ gcn_dwarf_register_span (rtx rtl)
#define TARGET_EMUTLS_VAR_INIT gcn_emutls_var_init
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN gcn_expand_builtin
+#undef TARGET_FRAME_POINTER_REQUIRED
+#define TARGET_FRAME_POINTER_REQUIRED gcn_frame_pointer_rqd
#undef TARGET_FUNCTION_ARG
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE gcn_function_arg_advance
diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index 540835b..5822ec3 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -88,6 +88,7 @@
#define FIRST_PARM_OFFSET(FNDECL) 0
#define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant (Pmode, (FP), -16)
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN 16
#define STACK_DYNAMIC_OFFSET(FNDECL) (-crtl->outgoing_args_size)
#define ACCUMULATE_OUTGOING_ARGS 1
#define RETURN_ADDR_RTX(COUNT,FRAMEADDR) \
@@ -138,7 +139,8 @@
#define WORK_ITEM_ID_Z_REG 162
#define SOFT_ARG_REG 416
#define FRAME_POINTER_REGNUM 418
-#define FIRST_PSEUDO_REGISTER 420
+#define DWARF_LINK_REGISTER 420
+#define FIRST_PSEUDO_REGISTER 421
#define FIRST_PARM_REG 24
#define NUM_PARM_REGS 6
@@ -200,7 +202,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Other registers. */ \
- 1, 1, 1, 1 \
+ 1, 1, 1, 1, 1 \
}
#define CALL_USED_REGISTERS { \
@@ -238,7 +240,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Other registers. */ \
- 1, 1, 1, 1 \
+ 1, 1, 1, 1, 1 \
}
@@ -517,7 +519,7 @@ enum gcn_address_spaces
"v236", "v237", "v238", "v239", "v240", "v241", "v242", "v243", "v244", \
"v245", "v246", "v247", "v248", "v249", "v250", "v251", "v252", "v253", \
"v254", "v255", \
- "?ap0", "?ap1", "?fp0", "?fp1" }
+ "?ap0", "?ap1", "?fp0", "?fp1", "?dwlr" }
#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index d7efa97..744337d 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -28,8 +28,8 @@ along with GCC; see the file COPYING3. If not see
extern unsigned int compute_mov_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 *);
+extern const char *output_a_shift (rtx[4], rtx_code);
+extern unsigned int compute_a_shift_length (rtx[4], rtx_code);
extern const char *output_a_rotate (enum rtx_code, rtx *);
extern unsigned int compute_a_rotate_length (rtx *);
extern const char *output_simode_bld (int, rtx[]);
@@ -41,7 +41,7 @@ extern const char *output_logical_op (machine_mode, rtx_code code,
extern unsigned int compute_logical_op_length (machine_mode, rtx_code,
rtx *, rtx_insn *);
-extern int compute_a_shift_cc (rtx, rtx *);
+extern int compute_a_shift_cc (rtx *, rtx_code);
#ifdef HAVE_ATTR_cc
extern enum attr_cc compute_plussi_cc (rtx *);
#endif
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index d8b4bfc..d2f6548 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1108,18 +1108,17 @@ h8300_and_costs (rtx x)
static int
h8300_shift_costs (rtx x)
{
- rtx operands[4];
+ rtx operands[3];
if (GET_MODE (x) != QImode
&& GET_MODE (x) != HImode
&& GET_MODE (x) != SImode)
return 100;
- operands[0] = NULL;
+ operands[0] = gen_rtx_REG (GET_MODE (x), 0);
operands[1] = NULL;
operands[2] = XEXP (x, 1);
- operands[3] = x;
- return compute_a_shift_length (operands) / 2;
+ return compute_a_shift_length (operands, GET_CODE (x)) / 2;
}
/* Worker function for TARGET_RTX_COSTS. */
@@ -3759,13 +3758,13 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
switch (shift_type)
{
case SHIFT_ASHIFT:
- info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
+ info->special = "mov.w\t%e0,%f3\n\tmov.b\t%s3,%t3\n\tmov.b\t%t0,%s3\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f3,%e0";
goto end;
case SHIFT_LSHIFTRT:
- info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
+ info->special = "mov.w\t%e0,%f3\n\tmov.b\t%t0,%s0\n\tmov.b\t%s3,%t0\n\tmov.b\t%t3,%s3\n\textu.w\t%f3\n\tmov.w\t%f3,%e0";
goto end;
case SHIFT_ASHIFTRT:
- info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
+ info->special = "mov.w\t%e0,%f3\n\tmov.b\t%t0,%s0\n\tmov.b\t%s3,%t0\n\tmov.b\t%t3,%s3\n\texts.w\t%f3\n\tmov.w\t%f3,%e0";
goto end;
}
}
@@ -3985,12 +3984,10 @@ h8300_shift_needs_scratch_p (int count, machine_mode mode, enum rtx_code type)
/* Output the assembler code for doing shifts. */
const char *
-output_a_shift (rtx *operands)
+output_a_shift (rtx operands[4], rtx_code code)
{
static int loopend_lab;
- rtx shift = operands[3];
- machine_mode mode = GET_MODE (shift);
- enum rtx_code code = GET_CODE (shift);
+ machine_mode mode = GET_MODE (operands[0]);
enum shift_type shift_type;
enum shift_mode shift_mode;
struct shift_info info;
@@ -4114,10 +4111,10 @@ output_a_shift (rtx *operands)
if (info.shift2 != NULL)
{
fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
- names_big[REGNO (operands[4])]);
+ names_big[REGNO (operands[3])]);
fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
output_asm_insn (info.shift2, operands);
- output_asm_insn ("add #0xff,%X4", operands);
+ output_asm_insn ("add #0xff,%X3", operands);
fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
if (n % 2)
output_asm_insn (info.shift1, operands);
@@ -4125,10 +4122,10 @@ output_a_shift (rtx *operands)
else
{
fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
- names_big[REGNO (operands[4])]);
+ names_big[REGNO (operands[3])]);
fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
output_asm_insn (info.shift1, operands);
- output_asm_insn ("add #0xff,%X4", operands);
+ output_asm_insn ("add #0xff,%X3", operands);
fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
}
return "";
@@ -4155,11 +4152,9 @@ h8300_asm_insn_count (const char *templ)
/* Compute the length of a shift insn. */
unsigned int
-compute_a_shift_length (rtx *operands)
+compute_a_shift_length (rtx operands[3], rtx_code code)
{
- rtx shift = operands[3];
- machine_mode mode = GET_MODE (shift);
- enum rtx_code code = GET_CODE (shift);
+ enum machine_mode mode = GET_MODE (operands[0]);
enum shift_type shift_type;
enum shift_mode shift_mode;
struct shift_info info;
@@ -4302,11 +4297,9 @@ compute_a_shift_length (rtx *operands)
/* Compute which flag bits are valid after a shift insn. */
int
-compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
+compute_a_shift_cc (rtx operands[3], rtx_code code)
{
- rtx shift = operands[3];
- machine_mode mode = GET_MODE (shift);
- enum rtx_code code = GET_CODE (shift);
+ machine_mode mode = GET_MODE (operands[0]);
enum shift_type shift_type;
enum shift_mode shift_mode;
struct shift_info info;
@@ -4363,16 +4356,18 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
{
case SHIFT_SPECIAL:
if (info.remainder == 0)
- return info.cc_special;
+ return (info.cc_special == OLD_CC_SET_ZN
+ || info.cc_special == OLD_CC_SET_ZNV);
/* Fall through. */
case SHIFT_INLINE:
- return info.cc_inline;
+ return (info.cc_inline == OLD_CC_SET_ZN
+ || info.cc_inline == OLD_CC_SET_ZNV);
case SHIFT_ROT_AND:
/* This case always ends with an and instruction. */
- return OLD_CC_SET_ZNV;
+ return true;
case SHIFT_LOOP:
/* A loop to shift by a "large" constant value.
@@ -4380,9 +4375,11 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
if (info.shift2 != NULL)
{
if (n % 2)
- return info.cc_inline;
+ return (info.cc_inline == OLD_CC_SET_ZN
+ || info.cc_inline == OLD_CC_SET_ZNV);
+
}
- return OLD_CC_CLOBBER;
+ return false;
default:
gcc_unreachable ();
diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md
index 7b6a66a..e1f0418 100644
--- a/gcc/config/h8300/jumpcall.md
+++ b/gcc/config/h8300/jumpcall.md
@@ -23,13 +23,32 @@
""
"#"
"&& reload_completed"
- [(set (reg:H8cc CC_REG)
- (compare:H8cc (match_dup 1) (match_dup 2)))
+ [(set (match_dup 4)
+ (match_dup 5))
(set (pc)
(if_then_else (match_op_dup 0
- [(reg:H8cc CC_REG) (const_int 0)])
+ [(match_dup 4) (const_int 0)])
(label_ref (match_dup 3)) (pc)))]
- "")
+ "
+{
+ machine_mode mode;
+
+ if (REG_P (operands[1])
+ && operands[2] == const0_rtx
+ && (GET_CODE (operands[0]) == EQ
+ || GET_CODE (operands[0]) == NE
+ || GET_CODE (operands[0]) == LT
+ || GET_CODE (operands[0]) == GE
+ /* Our tstxx insns will set ZN and clear V, so we can handle
+ a couple additional cases. */
+ || GET_CODE (operands[0]) == LE
+ || GET_CODE (operands[0]) == GT))
+ mode = E_CCZNmode;
+ else
+ mode = E_CCmode;
+ operands[4] = gen_rtx_REG (mode, CC_REG);
+ operands[5] = gen_rtx_COMPARE (mode, operands[1], operands[2]);
+}")
(define_insn "*branch_1"
[(set (pc)
diff --git a/gcc/config/h8300/predicates.md b/gcc/config/h8300/predicates.md
index f4e3ed4..bed23e9 100644
--- a/gcc/config/h8300/predicates.md
+++ b/gcc/config/h8300/predicates.md
@@ -506,6 +506,8 @@
{
if (GET_MODE (op) == mode
&& (GET_CODE (XEXP (op, 0)) != PRE_DEC
+ && GET_CODE (XEXP (op, 0)) != PRE_INC
+ && GET_CODE (XEXP (op, 0)) != POST_DEC
&& GET_CODE (XEXP (op, 0)) != POST_INC))
return 1;
return 0;
diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md
index 23140d9a..d3aa6be 100644
--- a/gcc/config/h8300/shiftrotate.md
+++ b/gcc/config/h8300/shiftrotate.md
@@ -150,174 +150,224 @@
}
[(set_attr "length" "4")])
-(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 (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")]))]
+ (shifts:QI
+ (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])))"
+ <CODE>))"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
(clobber (reg:CC CC_REG))])])
(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")]))
+ (shifts:QI
+ (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])))"
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>))"
{
- return output_a_shift (operands);
+ return output_a_shift (operands, <CODE>);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (operands)"))])
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
-(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"))]
+(define_insn "*shiftqi_noscratch_set_flags"
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (shifts:QI
+ (match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn"))
+ (const_int 0)))
+ (set (match_operand:QI 0 "register_operand" "=r,r")
+ (shifts:QI (match_dup 1) (match_dup 2)))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>)
+ && compute_a_shift_cc (operands, <CODE>))"
+{
+ return output_a_shift (operands, <CODE>);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
+
+(define_insn_and_split "*shiftqi"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (shifts:QI
+ (match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))]
""
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
- (clobber (match_dup 4))
+ [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
+ (clobber (match_dup 3))
(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"))
+(define_insn "*shiftqi_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (shifts:QI
+ (match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))
(clobber (reg:CC CC_REG))]
""
{
- return output_a_shift (operands);
+ return output_a_shift (operands, <CODE>);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (operands)"))])
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
(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")]))]
+ (shifts:HI
+ (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])))"
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>))"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ [(parallel [(set (match_dup 0) (shifts:HI (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")]))
+ (shifts:HI
+ (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])))"
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>))"
{
- return output_a_shift (operands);
+ return output_a_shift (operands, <CODE>);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (operands)"))])
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
-(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"))]
+(define_insn "*shifthi_noscratch_setzn"
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (shifts:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "nonmemory_operand" "S,rn"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "register_operand" "=r,r")
+ (shifts:HI (match_dup 1) (match_dup 2)))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>)
+ && compute_a_shift_cc (operands, <CODE>))"
+{
+ return output_a_shift (operands, <CODE>);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
+(define_insn_and_split "*shifthi"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (shifts:HI
+ (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "S,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))]
""
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
- (clobber (match_dup 4))
+ [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2)))
+ (clobber (match_dup 3))
(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"))
+(define_insn "*shifthi_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (shifts:HI
+ (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "S,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))
(clobber (reg:CC CC_REG))]
""
{
- return output_a_shift (operands);
+ return output_a_shift (operands, <CODE>);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (operands)"))])
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
(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")]))]
+ (shifts:SI
+ (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])))"
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>))"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ [(parallel [(set (match_dup 0) (shifts:SI (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")]))
+ (shifts:SI
+ (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])))"
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>))"
{
- return output_a_shift (operands);
+ return output_a_shift (operands, <CODE>);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (operands)"))])
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
+(define_insn "*shiftsi_noscratch_cczn"
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (shifts:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "T,rn"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r,r")
+ (shifts:SI (match_dup 1) (match_dup 2)))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>)
+ && compute_a_shift_cc (operands, <CODE>))"
+{
+ return output_a_shift (operands, <CODE>);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
;; Split a variable shift into a loop. If the register containing
;; the shift count dies, then we just use that register.
+
+(define_insn_and_split "*shiftsi"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (shifts:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))]
+ ""
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2)))
+ (clobber (match_dup 3))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftsi_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (shifts:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+ (clobber (match_scratch:QI 3 "=X,&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
+{
+ return output_a_shift (operands, <CODE>);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
(define_split
[(set (match_operand 0 "register_operand" "")
(match_operator 2 "nshift_operator"
@@ -327,18 +377,25 @@
(clobber (reg:CC CC_REG))]
"epilogue_completed
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN (match_dup 1) (const_int 0)))
+ (set (pc)
+ (if_then_else (le (reg:CCZN CC_REG) (const_int 0))
(label_ref (match_dup 5))
(pc)))
(match_dup 4)
(parallel
[(set (match_dup 0)
(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)))
+ (clobber (reg:CC CC_REG))])
+ (parallel
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (plus:QI (match_dup 1) (const_int -1))
+ (const_int 0)))
+ (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))])
(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
+ (if_then_else (ne (reg:CCZN CC_REG) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
@@ -356,20 +413,27 @@
(clobber (reg:CC CC_REG))]
"epilogue_completed
&& !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
- [(set (match_dup 3)
- (match_dup 1))
+ [(parallel
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN (match_dup 1) (const_int 0)))
+ (set (match_dup 3) (match_dup 1))])
(set (pc)
- (if_then_else (le (match_dup 3) (const_int 0))
+ (if_then_else (le (reg:CCZN CC_REG) (const_int 0))
(label_ref (match_dup 5))
(pc)))
(match_dup 4)
(parallel
[(set (match_dup 0)
(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)))
+ (clobber (reg:CC CC_REG))])
+ (parallel
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (plus:QI (match_dup 3) (const_int -1))
+ (const_int 0)))
+ (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))])
(set (pc)
- (if_then_else (ne (match_dup 3) (const_int 0))
+ (if_then_else (ne (reg:CCZN CC_REG) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 5312003..bac3219 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -25,15 +25,6 @@ along with GCC; see the file COPYING3. If not see
#undef DARWIN_X86
#define DARWIN_X86 1
-#ifdef IN_LIBGCC2
-#undef TARGET_64BIT
-#ifdef __x86_64__
-#define TARGET_64BIT 1
-#else
-#define TARGET_64BIT 0
-#endif
-#endif
-
/* WORKAROUND pr80556:
For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
from libSystem). This doesn't use the keymgr (see keymgr.c) and therefore
@@ -44,11 +35,15 @@ along with GCC; see the file COPYING3. If not see
even when static-libgcc is specified. We put libSystem first so that
unwinder symbols are satisfied from there.
We default to 64b for single-arch builds, so apply this unconditionally. */
+#ifndef PR80556_WORKAROUND
+#define PR80556_WORKAROUND \
+" %:version-compare(>= 10.6 mmacosx-version-min= -lSystem) "
+#endif
#undef REAL_LIBGCC_SPEC
#define REAL_LIBGCC_SPEC \
- "%{static-libgcc|static: \
- %:version-compare(>= 10.6 mmacosx-version-min= -lSystem) \
- -lgcc_eh -lgcc; \
+ "%{static-libgcc|static: " \
+ PR80556_WORKAROUND \
+ " -lgcc_eh -lgcc; \
shared-libgcc|fexceptions|fgnu-runtime: \
%:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \
%:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
@@ -142,8 +137,11 @@ along with GCC; see the file COPYING3. If not see
%{mpc64:crtprec64.o%s} \
%{mpc80:crtprec80.o%s}" TM_DESTRUCTOR
+#ifndef DARWIN_ARCH_SPEC
/* We default to x86_64 for single-arch builds, bi-arch overrides. */
#define DARWIN_ARCH_SPEC "x86_64"
+#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
+#endif
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
diff --git a/gcc/config/i386/darwin32-biarch.h b/gcc/config/i386/darwin32-biarch.h
index 73b83eb..5470edf 100644
--- a/gcc/config/i386/darwin32-biarch.h
+++ b/gcc/config/i386/darwin32-biarch.h
@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see
#undef DARWIN_ARCH_SPEC
#define DARWIN_ARCH_SPEC "%{m64:x86_64;:i386}"
+#define TARGET_64BIT_DEFAULT 0
+#define TARGET_BI_ARCH 1
+
/* WORKAROUND pr80556:
For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
from libSystem). This doesn't use the keymgr (see keymgr.c) and therefore
@@ -30,22 +33,9 @@ along with GCC; see the file COPYING3. If not see
Therefore, for 64b exes at least, we must use the libunwind implementation,
even when static-libgcc is specified. We put libSystem first so that
unwinder symbols are satisfied from there. */
-#undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC \
- "%{static-libgcc|static: \
- %{m64:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} \
- -lgcc_eh -lgcc; \
- shared-libgcc|fexceptions|fgnu-runtime: \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \
- %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
- %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
- -lgcc ; \
- :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
- %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
- %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
- -lgcc }"
+#undef PR80556_WORKAROUND
+#define PR80556_WORKAROUND \
+" %{m64:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} "
#undef DARWIN_SUBARCH_SPEC
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
diff --git a/gcc/config/i386/darwin64-biarch.h b/gcc/config/i386/darwin64-biarch.h
index 1ae76b8..f5bc3d6 100644
--- a/gcc/config/i386/darwin64-biarch.h
+++ b/gcc/config/i386/darwin64-biarch.h
@@ -22,6 +22,9 @@ along with GCC; see the file COPYING3. If not see
#undef DARWIN_ARCH_SPEC
#define DARWIN_ARCH_SPEC "%{m32:i386;:x86_64}"
+#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64)
+#define TARGET_BI_ARCH 1
+
/* WORKAROUND pr80556:
For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
from libSystem). This doesn't use the keymgr (see keymgr.c) and therefore
@@ -31,22 +34,9 @@ along with GCC; see the file COPYING3. If not see
Therefore, for 64b exes at least, we must use the libunwind implementation,
even when static-libgcc is specified. We put libSystem first so that
unwinder symbols are satisfied from there. */
-#undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC \
- "%{static-libgcc|static: \
- %{!m32:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} \
- -lgcc_eh -lgcc; \
- shared-libgcc|fexceptions|fgnu-runtime: \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \
- %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
- %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
- -lgcc ; \
- :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
- %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
- %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
- %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
- -lgcc }"
+#undef PR80556_WORKAROUND
+#define PR80556_WORKAROUND \
+" %{!m32:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} "
#undef DARWIN_SUBARCH_SPEC
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
diff --git a/gcc/config/i386/gcc-auto-profile b/gcc/config/i386/gcc-auto-profile
index 5da5c63..56f64cb 100755
--- a/gcc/config/i386/gcc-auto-profile
+++ b/gcc/config/i386/gcc-auto-profile
@@ -1,7 +1,7 @@
#!/bin/sh
-# profile workload for gcc profile feedback (autofdo) using Linux perf
-# auto generated. to regenerate for new CPUs run
-# contrib/gen_autofdo_event.py --shell --all in gcc source
+# Profile workload for gcc profile feedback (autofdo) using Linux perf.
+# Auto generated. To regenerate for new CPUs run
+# contrib/gen_autofdo_event.py --script --all in gcc source
# usages:
# gcc-auto-profile program (profile program and children)
@@ -10,7 +10,7 @@
# gcc-auto-profile --kernel -a sleep X (profile kernel)
# gcc-auto-profile --all -a sleep X (profile kernel and user space)
-# identify branches taken event for CPU
+# Identify branches taken event for CPU.
#
FLAGS=u
@@ -37,7 +37,12 @@ case `egrep -q "^cpu family\s*: 6" /proc/cpuinfo &&
egrep "^model\s*:" /proc/cpuinfo | head -n1` in
model*:\ 55|\
model*:\ 77|\
-model*:\ 76) E="cpu/event=0xC4,umask=0xFE/p$FLAGS" ;;
+model*:\ 76|\
+model*:\ 92|\
+model*:\ 95|\
+model*:\ 87|\
+model*:\ 133|\
+model*:\ 122) E="cpu/event=0xC4,umask=0xFE/p$FLAGS" ;;
model*:\ 42|\
model*:\ 45|\
model*:\ 58|\
@@ -48,9 +53,16 @@ model*:\ 70|\
model*:\ 63|\
model*:\ 61|\
model*:\ 71|\
+model*:\ 79|\
model*:\ 86|\
model*:\ 78|\
-model*:\ 94) E="cpu/event=0xC4,umask=0x20/p$FLAGS" ;;
+model*:\ 94|\
+model*:\ 142|\
+model*:\ 158|\
+model*:\ 165|\
+model*:\ 166|\
+model*:\ 85|\
+model*:\ 85) E="cpu/event=0xC4,umask=0x20/p$FLAGS" ;;
model*:\ 46|\
model*:\ 30|\
model*:\ 31|\
@@ -63,8 +75,23 @@ model*:\ 38|\
model*:\ 39|\
model*:\ 54|\
model*:\ 53) E="cpu/event=0x88,umask=0x41/p$FLAGS" ;;
+model*:\ 126|\
+model*:\ 140|\
+model*:\ 141|\
+model*:\ 106|\
+model*:\ 108) E="cpu/event=0xc4,umask=0x20/p$FLAGS" ;;
*)
echo >&2 "Unknown CPU. Run contrib/gen_autofdo_event.py --all --script to update script."
exit 1 ;;
esac
-exec perf record -e $E -b "$@"
+set -x
+if ! perf record -e $E -b "$@" ; then
+ # PEBS may not actually be working even if the processor supports it
+ # (e.g., in a virtual machine). Trying to run without /p.
+ set +x
+ echo >&2 "Retrying without /p."
+ E="$(echo "${E}" | sed -e 's/\/p/\//')"
+ set -x
+ exec perf record -e $E -b "$@"
+ set +x
+fi
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index e9763eb..69ea79e 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -190,6 +190,82 @@ ix86_expand_clear (rtx dest)
emit_insn (tmp);
}
+/* Return true if V can be broadcasted from an integer of WIDTH bits
+ which is returned in VAL_BROADCAST. Otherwise, return false. */
+
+static bool
+ix86_broadcast (HOST_WIDE_INT v, unsigned int width,
+ HOST_WIDE_INT &val_broadcast)
+{
+ wide_int val = wi::uhwi (v, HOST_BITS_PER_WIDE_INT);
+ val_broadcast = wi::extract_uhwi (val, 0, width);
+ for (unsigned int i = width; i < HOST_BITS_PER_WIDE_INT; i += width)
+ {
+ HOST_WIDE_INT each = wi::extract_uhwi (val, i, width);
+ if (val_broadcast != each)
+ return false;
+ }
+ val_broadcast = sext_hwi (val_broadcast, width);
+ return true;
+}
+
+/* Convert the CONST_WIDE_INT operand OP to broadcast in MODE. */
+
+static rtx
+ix86_convert_const_wide_int_to_broadcast (machine_mode mode, rtx op)
+{
+ /* Don't use integer vector broadcast if we can't move from GPR to SSE
+ register directly. */
+ if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
+ return nullptr;
+
+ /* Convert CONST_WIDE_INT to a non-standard SSE constant integer
+ broadcast only if vector broadcast is available. */
+ if (!TARGET_AVX
+ || !CONST_WIDE_INT_P (op)
+ || standard_sse_constant_p (op, mode))
+ return nullptr;
+
+ HOST_WIDE_INT val = CONST_WIDE_INT_ELT (op, 0);
+ HOST_WIDE_INT val_broadcast;
+ scalar_int_mode broadcast_mode;
+ if (TARGET_AVX2
+ && ix86_broadcast (val, GET_MODE_BITSIZE (QImode),
+ val_broadcast))
+ broadcast_mode = QImode;
+ else if (TARGET_AVX2
+ && ix86_broadcast (val, GET_MODE_BITSIZE (HImode),
+ val_broadcast))
+ broadcast_mode = HImode;
+ else if (ix86_broadcast (val, GET_MODE_BITSIZE (SImode),
+ val_broadcast))
+ broadcast_mode = SImode;
+ else if (TARGET_64BIT
+ && ix86_broadcast (val, GET_MODE_BITSIZE (DImode),
+ val_broadcast))
+ broadcast_mode = DImode;
+ else
+ return nullptr;
+
+ /* Check if OP can be broadcasted from VAL. */
+ for (int i = 1; i < CONST_WIDE_INT_NUNITS (op); i++)
+ if (val != CONST_WIDE_INT_ELT (op, i))
+ return nullptr;
+
+ unsigned int nunits = (GET_MODE_SIZE (mode)
+ / GET_MODE_SIZE (broadcast_mode));
+ machine_mode vector_mode;
+ if (!mode_for_vector (broadcast_mode, nunits).exists (&vector_mode))
+ gcc_unreachable ();
+ rtx target = ix86_gen_scratch_sse_rtx (vector_mode);
+ bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
+ target,
+ GEN_INT (val_broadcast));
+ gcc_assert (ok);
+ target = lowpart_subreg (mode, target, vector_mode);
+ return target;
+}
+
void
ix86_expand_move (machine_mode mode, rtx operands[])
{
@@ -347,20 +423,29 @@ ix86_expand_move (machine_mode mode, rtx operands[])
&& optimize)
op1 = copy_to_mode_reg (mode, op1);
- if (can_create_pseudo_p ()
- && CONST_DOUBLE_P (op1))
+ if (can_create_pseudo_p ())
{
- /* If we are loading a floating point constant to a register,
- force the value to memory now, since we'll get better code
- out the back end. */
+ if (CONST_DOUBLE_P (op1))
+ {
+ /* If we are loading a floating point constant to a
+ register, force the value to memory now, since we'll
+ get better code out the back end. */
- op1 = validize_mem (force_const_mem (mode, op1));
- if (!register_operand (op0, mode))
+ op1 = validize_mem (force_const_mem (mode, op1));
+ if (!register_operand (op0, mode))
+ {
+ rtx temp = gen_reg_rtx (mode);
+ emit_insn (gen_rtx_SET (temp, op1));
+ emit_move_insn (op0, temp);
+ return;
+ }
+ }
+ else if (GET_MODE_SIZE (mode) >= 16)
{
- rtx temp = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (temp, op1));
- emit_move_insn (op0, temp);
- return;
+ rtx tmp = ix86_convert_const_wide_int_to_broadcast
+ (GET_MODE (op0), op1);
+ if (tmp != nullptr)
+ op1 = tmp;
}
}
}
@@ -368,6 +453,62 @@ ix86_expand_move (machine_mode mode, rtx operands[])
emit_insn (gen_rtx_SET (op0, op1));
}
+static rtx
+ix86_broadcast_from_integer_constant (machine_mode mode, rtx op)
+{
+ int nunits = GET_MODE_NUNITS (mode);
+ if (nunits < 2)
+ return nullptr;
+
+ /* Don't use integer vector broadcast if we can't move from GPR to SSE
+ register directly. */
+ if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
+ return nullptr;
+
+ /* Convert CONST_VECTOR to a non-standard SSE constant integer
+ broadcast only if vector broadcast is available. */
+ if (!(TARGET_AVX2
+ || (TARGET_AVX
+ && (GET_MODE_INNER (mode) == SImode
+ || GET_MODE_INNER (mode) == DImode)))
+ || standard_sse_constant_p (op, mode))
+ return nullptr;
+
+ /* Don't broadcast from a 64-bit integer constant in 32-bit mode. */
+ if (GET_MODE_INNER (mode) == DImode && !TARGET_64BIT)
+ return nullptr;
+
+ if (GET_MODE_INNER (mode) == TImode)
+ return nullptr;
+
+ rtx constant = get_pool_constant (XEXP (op, 0));
+ if (GET_CODE (constant) != CONST_VECTOR)
+ return nullptr;
+
+ /* There could be some rtx like
+ (mem/u/c:V16QI (symbol_ref/u:DI ("*.LC1")))
+ but with "*.LC1" refer to V2DI constant vector. */
+ if (GET_MODE (constant) != mode)
+ {
+ constant = simplify_subreg (mode, constant, GET_MODE (constant),
+ 0);
+ if (constant == nullptr || GET_CODE (constant) != CONST_VECTOR)
+ return nullptr;
+ }
+
+ rtx first = XVECEXP (constant, 0, 0);
+
+ for (int i = 1; i < nunits; ++i)
+ {
+ rtx tmp = XVECEXP (constant, 0, i);
+ /* Vector duplicate value. */
+ if (!rtx_equal_p (tmp, first))
+ return nullptr;
+ }
+
+ return first;
+}
+
void
ix86_expand_vector_move (machine_mode mode, rtx operands[])
{
@@ -407,7 +548,36 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[])
op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
}
else
- op1 = validize_mem (force_const_mem (mode, op1));
+ {
+ machine_mode mode = GET_MODE (op0);
+ rtx tmp = ix86_convert_const_wide_int_to_broadcast
+ (mode, op1);
+ if (tmp == nullptr)
+ op1 = validize_mem (force_const_mem (mode, op1));
+ else
+ op1 = tmp;
+ }
+ }
+
+ if (can_create_pseudo_p ()
+ && GET_MODE_SIZE (mode) >= 16
+ && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ && (MEM_P (op1)
+ && SYMBOL_REF_P (XEXP (op1, 0))
+ && CONSTANT_POOL_ADDRESS_P (XEXP (op1, 0))))
+ {
+ rtx first = ix86_broadcast_from_integer_constant (mode, op1);
+ if (first != nullptr)
+ {
+ /* Broadcast to XMM/YMM/ZMM register from an integer
+ constant. */
+ op1 = ix86_gen_scratch_sse_rtx (mode);
+ bool ok = ix86_expand_vector_init_duplicate (false, mode,
+ op1, first);
+ gcc_assert (ok);
+ emit_move_insn (op0, op1);
+ return;
+ }
}
/* We need to check memory alignment for SSE mode since attribute
@@ -763,6 +933,7 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
switch (mode)
{
+ case E_V4QImode:
case E_V8QImode:
sse_mode = V16QImode;
double_sse_mode = V32QImode;
@@ -779,6 +950,7 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
break;
case E_V4HImode:
+ case E_V2HImode:
sse_mode = V8HImode;
double_sse_mode = V16HImode;
mask = gen_rtx_PARALLEL (VOIDmode,
@@ -821,7 +993,7 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
rtx insn = gen_rtx_SET (dest, op2);
emit_insn (insn);
- /* Move bits 64:127 to bits 0:63. */
+ /* Move high bits to low bits. */
if (high_p)
{
if (sse_mode == V4SFmode)
@@ -834,9 +1006,19 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
}
else
{
- mask = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (4, GEN_INT (2), GEN_INT (3),
- GEN_INT (0), GEN_INT (1)));
+ int sz = GET_MODE_SIZE (mode);
+
+ if (sz == 4)
+ mask = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4, GEN_INT (1), GEN_INT (0),
+ GEN_INT (0), GEN_INT (1)));
+ else if (sz == 8)
+ mask = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4, GEN_INT (2), GEN_INT (3),
+ GEN_INT (0), GEN_INT (1)));
+ else
+ gcc_unreachable ();
+
dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
}
@@ -3571,7 +3753,7 @@ ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
cmp_op0 = force_reg (cmp_ops_mode, cmp_op0);
- int (*op1_predicate)(rtx, machine_mode)
+ bool (*op1_predicate)(rtx, machine_mode)
= VECTOR_MODE_P (cmp_ops_mode) ? vector_operand : nonimmediate_operand;
if (!op1_predicate (cmp_op1, cmp_ops_mode))
@@ -5173,6 +5355,12 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
else
unpack = gen_sse4_1_sign_extendv2hiv2si2;
break;
+ case E_V4QImode:
+ if (unsigned_p)
+ unpack = gen_sse4_1_zero_extendv2qiv2hi2;
+ else
+ unpack = gen_sse4_1_sign_extendv2qiv2hi2;
+ break;
default:
gcc_unreachable ();
}
@@ -5198,6 +5386,12 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
emit_insn (gen_mmx_lshrv1di3 (tmp, gen_lowpart (V1DImode, src),
GEN_INT (32)));
break;
+ case 4:
+ /* Shift higher 2 bytes to lower 2 bytes. */
+ tmp = gen_reg_rtx (V1SImode);
+ emit_insn (gen_mmx_lshrv1si3 (tmp, gen_lowpart (V1SImode, src),
+ GEN_INT (16)));
+ break;
default:
gcc_unreachable ();
}
@@ -5245,6 +5439,12 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
else
unpack = gen_mmx_punpcklwd;
break;
+ case E_V4QImode:
+ if (high_p)
+ unpack = gen_mmx_punpckhbw_low;
+ else
+ unpack = gen_mmx_punpcklbw_low;
+ break;
default:
gcc_unreachable ();
}
@@ -8210,6 +8410,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
pop = NULL;
gcc_assert (!TARGET_64BIT || !pop);
+ rtx addr = XEXP (fnaddr, 0);
if (TARGET_MACHO && !TARGET_64BIT)
{
#if TARGET_MACHO
@@ -8222,7 +8423,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
/* Static functions and indirect calls don't need the pic register. Also,
check if PLT was explicitly avoided via no-plt or "noplt" attribute, making
it an indirect call. */
- rtx addr = XEXP (fnaddr, 0);
if (flag_pic
&& GET_CODE (addr) == SYMBOL_REF
&& !SYMBOL_REF_LOCAL_P (addr))
@@ -8385,6 +8585,20 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
}
}
+ if (TARGET_MACHO && TARGET_64BIT && !sibcall
+ && ((GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
+ || !fndecl || TREE_PUBLIC (fndecl)))
+ {
+ /* We allow public functions defined in a TU to bind locally for PIC
+ code (the default) on 64bit Mach-O.
+ If such functions are not inlined, we cannot tell at compile-time if
+ they will be called via the lazy symbol resolver (this can depend on
+ options given at link-time). Therefore, we must assume that the lazy
+ resolver could be used which clobbers R11 and R10. */
+ clobber_reg (&use, gen_rtx_REG (DImode, R11_REG));
+ clobber_reg (&use, gen_rtx_REG (DImode, R10_REG));
+ }
+
if (vec_len > 1)
call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
rtx_insn *call_insn = emit_call_insn (call);
@@ -11586,10 +11800,24 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
if (target == 0)
target = gen_reg_rtx (QImode);
- pat = gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (target, pat));
+ /* NB: For aesenc/aesdec keylocker insn, ZF will be set when runtime
+ error occurs. Then the output should be cleared for safety. */
+ rtx_code_label *ok_label;
+ rtx tmp;
+
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
+ pat = gen_rtx_EQ (QImode, tmp, const0_rtx);
+ ok_label = gen_label_rtx ();
+ emit_cmp_and_jump_insns (tmp, const0_rtx, NE, 0, GET_MODE (tmp),
+ true, ok_label);
+ /* Usually the runtime error seldom occur, so predict OK path as
+ hotspot to optimize it as fallthrough block. */
+ predict_jump (REG_BR_PROB_BASE * 90 / 100);
+ emit_insn (gen_rtx_SET (op1, const0_rtx));
+
+ emit_label (ok_label);
+ emit_insn (gen_rtx_SET (target, pat));
emit_insn (gen_rtx_SET (op0, op1));
return target;
@@ -11644,8 +11872,17 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
if (target == 0)
target = gen_reg_rtx (QImode);
- pat = gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
- const0_rtx);
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
+ pat = gen_rtx_EQ (QImode, tmp, const0_rtx);
+ ok_label = gen_label_rtx ();
+ emit_cmp_and_jump_insns (tmp, const0_rtx, NE, 0, GET_MODE (tmp),
+ true, ok_label);
+ predict_jump (REG_BR_PROB_BASE * 90 / 100);
+
+ for (i = 0; i < 8; i++)
+ emit_insn (gen_rtx_SET (xmm_regs[i], const0_rtx));
+
+ emit_label (ok_label);
emit_insn (gen_rtx_SET (target, pat));
for (i = 0; i < 8; i++)
@@ -13739,7 +13976,7 @@ static bool expand_vec_perm_1 (struct expand_vec_perm_d *d);
/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
with all elements equal to VAR. Return true if successful. */
-static bool
+bool
ix86_expand_vector_init_duplicate (bool mmx_ok, machine_mode mode,
rtx target, rtx val)
{
@@ -17138,7 +17375,8 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
;
else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 16
- || GET_MODE_SIZE (vmode) == 8))
+ || GET_MODE_SIZE (vmode) == 8
+ || GET_MODE_SIZE (vmode) == 4))
;
else
return false;
@@ -17215,7 +17453,9 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
vperm = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
vperm = force_reg (vmode, vperm);
- if (GET_MODE_SIZE (vmode) == 8)
+ if (GET_MODE_SIZE (vmode) == 4)
+ emit_insn (gen_mmx_pblendvb32 (target, op0, op1, vperm));
+ else if (GET_MODE_SIZE (vmode) == 8)
emit_insn (gen_mmx_pblendvb64 (target, op0, op1, vperm));
else if (GET_MODE_SIZE (vmode) == 16)
emit_insn (gen_sse4_1_pblendvb (target, op0, op1, vperm));
@@ -17247,6 +17487,16 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
vmode = V4HImode;
goto do_subreg;
+ case E_V4QImode:
+ for (i = 0; i < 4; i += 2)
+ if (d->perm[i] + 1 != d->perm[i + 1])
+ goto use_pblendvb;
+
+ for (i = 0; i < 2; ++i)
+ mask |= (d->perm[i * 2] >= 4) << i;
+ vmode = V2HImode;
+ goto do_subreg;
+
case E_V32QImode:
/* See if bytes move in pairs. If not, vpblendvb must be used. */
for (i = 0; i < 32; i += 2)
@@ -17504,163 +17754,176 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
nelt = d->nelt;
if (!d->one_operand_p)
- {
- if (GET_MODE_SIZE (d->vmode) == 8)
- {
- if (!TARGET_XOP)
- return false;
- vmode = V8QImode;
- }
- else if (GET_MODE_SIZE (d->vmode) == 16)
- {
- if (!TARGET_XOP)
- return false;
- }
- else if (GET_MODE_SIZE (d->vmode) == 32)
- {
- if (!TARGET_AVX2)
- return false;
+ switch (GET_MODE_SIZE (d->vmode))
+ {
+ case 4:
+ if (!TARGET_XOP)
+ return false;
+ vmode = V4QImode;
+ break;
- if (valid_perm_using_mode_p (V2TImode, d))
- {
- if (d->testing_p)
- return true;
+ case 8:
+ if (!TARGET_XOP)
+ return false;
+ vmode = V8QImode;
+ break;
- /* Use vperm2i128 insn. The pattern uses
- V4DImode instead of V2TImode. */
- target = d->target;
- if (d->vmode != V4DImode)
- target = gen_reg_rtx (V4DImode);
- op0 = gen_lowpart (V4DImode, d->op0);
- op1 = gen_lowpart (V4DImode, d->op1);
- rperm[0]
- = GEN_INT ((d->perm[0] / (nelt / 2))
- | ((d->perm[nelt / 2] / (nelt / 2)) * 16));
- emit_insn (gen_avx2_permv2ti (target, op0, op1, rperm[0]));
- if (target != d->target)
- emit_move_insn (d->target, gen_lowpart (d->vmode, target));
- return true;
- }
+ case 16:
+ if (!TARGET_XOP)
return false;
- }
- else
+ break;
+
+ case 32:
+ if (!TARGET_AVX2)
+ return false;
+
+ if (valid_perm_using_mode_p (V2TImode, d))
+ {
+ if (d->testing_p)
+ return true;
+
+ /* Use vperm2i128 insn. The pattern uses
+ V4DImode instead of V2TImode. */
+ target = d->target;
+ if (d->vmode != V4DImode)
+ target = gen_reg_rtx (V4DImode);
+ op0 = gen_lowpart (V4DImode, d->op0);
+ op1 = gen_lowpart (V4DImode, d->op1);
+ rperm[0]
+ = GEN_INT ((d->perm[0] / (nelt / 2))
+ | ((d->perm[nelt / 2] / (nelt / 2)) * 16));
+ emit_insn (gen_avx2_permv2ti (target, op0, op1, rperm[0]));
+ if (target != d->target)
+ emit_move_insn (d->target, gen_lowpart (d->vmode, target));
+ return true;
+ }
+ /* FALLTHRU */
+
+ default:
return false;
- }
+ }
else
- {
- if (GET_MODE_SIZE (d->vmode) == 8)
- {
- if (!TARGET_SSSE3)
- return false;
- vmode = V8QImode;
- }
- else if (GET_MODE_SIZE (d->vmode) == 16)
- {
- if (!TARGET_SSSE3)
- return false;
- }
- else if (GET_MODE_SIZE (d->vmode) == 32)
- {
- if (!TARGET_AVX2)
- return false;
+ switch (GET_MODE_SIZE (d->vmode))
+ {
+ case 4:
+ if (!TARGET_SSSE3)
+ return false;
+ vmode = V4QImode;
+ break;
- /* V4DImode should be already handled through
- expand_vselect by vpermq instruction. */
- gcc_assert (d->vmode != V4DImode);
+ case 8:
+ if (!TARGET_SSSE3)
+ return false;
+ vmode = V8QImode;
+ break;
- vmode = V32QImode;
- if (d->vmode == V8SImode
- || d->vmode == V16HImode
- || d->vmode == V32QImode)
- {
- /* First see if vpermq can be used for
- V8SImode/V16HImode/V32QImode. */
- if (valid_perm_using_mode_p (V4DImode, d))
- {
- for (i = 0; i < 4; i++)
- perm[i] = (d->perm[i * nelt / 4] * 4 / nelt) & 3;
- if (d->testing_p)
+ case 16:
+ if (!TARGET_SSSE3)
+ return false;
+ break;
+
+ case 32:
+ if (!TARGET_AVX2)
+ return false;
+
+ /* V4DImode should be already handled through
+ expand_vselect by vpermq instruction. */
+ gcc_assert (d->vmode != V4DImode);
+
+ vmode = V32QImode;
+ if (d->vmode == V8SImode
+ || d->vmode == V16HImode
+ || d->vmode == V32QImode)
+ {
+ /* First see if vpermq can be used for
+ V8SImode/V16HImode/V32QImode. */
+ if (valid_perm_using_mode_p (V4DImode, d))
+ {
+ for (i = 0; i < 4; i++)
+ perm[i] = (d->perm[i * nelt / 4] * 4 / nelt) & 3;
+ if (d->testing_p)
+ return true;
+ target = gen_reg_rtx (V4DImode);
+ if (expand_vselect (target, gen_lowpart (V4DImode, d->op0),
+ perm, 4, false))
+ {
+ emit_move_insn (d->target,
+ gen_lowpart (d->vmode, target));
return true;
- target = gen_reg_rtx (V4DImode);
- if (expand_vselect (target, gen_lowpart (V4DImode, d->op0),
- perm, 4, false))
- {
- emit_move_insn (d->target,
- gen_lowpart (d->vmode, target));
- return true;
- }
- return false;
- }
+ }
+ return false;
+ }
- /* Next see if vpermd can be used. */
- if (valid_perm_using_mode_p (V8SImode, d))
- vmode = V8SImode;
- }
- /* Or if vpermps can be used. */
- else if (d->vmode == V8SFmode)
- vmode = V8SImode;
+ /* Next see if vpermd can be used. */
+ if (valid_perm_using_mode_p (V8SImode, d))
+ vmode = V8SImode;
+ }
+ /* Or if vpermps can be used. */
+ else if (d->vmode == V8SFmode)
+ vmode = V8SImode;
- if (vmode == V32QImode)
- {
- /* vpshufb only works intra lanes, it is not
- possible to shuffle bytes in between the lanes. */
- for (i = 0; i < nelt; ++i)
- if ((d->perm[i] ^ i) & (nelt / 2))
- return false;
- }
- }
- else if (GET_MODE_SIZE (d->vmode) == 64)
- {
- if (!TARGET_AVX512BW)
- return false;
+ if (vmode == V32QImode)
+ {
+ /* vpshufb only works intra lanes, it is not
+ possible to shuffle bytes in between the lanes. */
+ for (i = 0; i < nelt; ++i)
+ if ((d->perm[i] ^ i) & (nelt / 2))
+ return false;
+ }
+ break;
- /* If vpermq didn't work, vpshufb won't work either. */
- if (d->vmode == V8DFmode || d->vmode == V8DImode)
- return false;
+ case 64:
+ if (!TARGET_AVX512BW)
+ return false;
- vmode = V64QImode;
- if (d->vmode == V16SImode
- || d->vmode == V32HImode
- || d->vmode == V64QImode)
- {
- /* First see if vpermq can be used for
- V16SImode/V32HImode/V64QImode. */
- if (valid_perm_using_mode_p (V8DImode, d))
- {
- for (i = 0; i < 8; i++)
- perm[i] = (d->perm[i * nelt / 8] * 8 / nelt) & 7;
- if (d->testing_p)
+ /* If vpermq didn't work, vpshufb won't work either. */
+ if (d->vmode == V8DFmode || d->vmode == V8DImode)
+ return false;
+
+ vmode = V64QImode;
+ if (d->vmode == V16SImode
+ || d->vmode == V32HImode
+ || d->vmode == V64QImode)
+ {
+ /* First see if vpermq can be used for
+ V16SImode/V32HImode/V64QImode. */
+ if (valid_perm_using_mode_p (V8DImode, d))
+ {
+ for (i = 0; i < 8; i++)
+ perm[i] = (d->perm[i * nelt / 8] * 8 / nelt) & 7;
+ if (d->testing_p)
+ return true;
+ target = gen_reg_rtx (V8DImode);
+ if (expand_vselect (target, gen_lowpart (V8DImode, d->op0),
+ perm, 8, false))
+ {
+ emit_move_insn (d->target,
+ gen_lowpart (d->vmode, target));
return true;
- target = gen_reg_rtx (V8DImode);
- if (expand_vselect (target, gen_lowpart (V8DImode, d->op0),
- perm, 8, false))
- {
- emit_move_insn (d->target,
- gen_lowpart (d->vmode, target));
- return true;
- }
- return false;
- }
+ }
+ return false;
+ }
- /* Next see if vpermd can be used. */
- if (valid_perm_using_mode_p (V16SImode, d))
- vmode = V16SImode;
- }
- /* Or if vpermps can be used. */
- else if (d->vmode == V16SFmode)
- vmode = V16SImode;
- if (vmode == V64QImode)
- {
- /* vpshufb only works intra lanes, it is not
- possible to shuffle bytes in between the lanes. */
- for (i = 0; i < nelt; ++i)
- if ((d->perm[i] ^ i) & (3 * nelt / 4))
- return false;
- }
- }
- else
+ /* Next see if vpermd can be used. */
+ if (valid_perm_using_mode_p (V16SImode, d))
+ vmode = V16SImode;
+ }
+ /* Or if vpermps can be used. */
+ else if (d->vmode == V16SFmode)
+ vmode = V16SImode;
+ if (vmode == V64QImode)
+ {
+ /* vpshufb only works intra lanes, it is not
+ possible to shuffle bytes in between the lanes. */
+ for (i = 0; i < nelt; ++i)
+ if ((d->perm[i] ^ i) & (3 * nelt / 4))
+ return false;
+ }
+ break;
+
+ default:
return false;
- }
+ }
if (d->testing_p)
return true;
@@ -17700,23 +17963,28 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
machine_mode vpmode = vmode;
- if (vmode == V8QImode)
+ if (vmode == V4QImode
+ || vmode == V8QImode)
{
rtx m128 = GEN_INT (-128);
/* Remap elements from the second operand, as we have to
- account for inactive top 8 elements from the first operand. */
+ account for inactive top elements from the first operand. */
if (!d->one_operand_p)
- for (i = 0; i < nelt; ++i)
- {
- int ival = INTVAL (rperm[i]);
- if (ival >= 8)
- ival += 8;
- rperm[i] = GEN_INT (ival);
- }
+ {
+ int sz = GET_MODE_SIZE (vmode);
+
+ for (i = 0; i < nelt; ++i)
+ {
+ int ival = INTVAL (rperm[i]);
+ if (ival >= sz)
+ ival += 16-sz;
+ rperm[i] = GEN_INT (ival);
+ }
+ }
- /* V8QI is emulated with V16QI instruction, fill inactive
- elements in the top 8 positions with zeros. */
+ /* V4QI/V8QI is emulated with V16QI instruction, fill inactive
+ elements in the top positions with zeros. */
for (i = nelt; i < 16; ++i)
rperm[i] = m128;
@@ -17738,7 +18006,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
{
rtx (*gen) (rtx, rtx, rtx);
- if (vmode == V8QImode)
+ if (vmode == V4QImode)
+ gen = gen_mmx_pshufbv4qi3;
+ else if (vmode == V8QImode)
gen = gen_mmx_pshufbv8qi3;
else if (vmode == V16QImode)
gen = gen_ssse3_pshufbv16qi3;
@@ -17765,7 +18035,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
op1 = gen_lowpart (vmode, d->op1);
- if (vmode == V8QImode)
+ if (vmode == V4QImode)
+ gen = gen_mmx_ppermv32;
+ else if (vmode == V8QImode)
gen = gen_mmx_ppermv64;
else if (vmode == V16QImode)
gen = gen_xop_pperm;
@@ -18212,7 +18484,8 @@ expand_vec_perm_pblendv (struct expand_vec_perm_d *d)
;
else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
;
- else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 8
+ else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 4
+ || GET_MODE_SIZE (vmode) == 8
|| GET_MODE_SIZE (vmode) == 16))
;
else
@@ -18292,7 +18565,8 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
rtx_insn *seq;
bool ok, same_halves = false;
- if (GET_MODE_SIZE (d->vmode) == 8
+ if (GET_MODE_SIZE (d->vmode) == 4
+ || GET_MODE_SIZE (d->vmode) == 8
|| GET_MODE_SIZE (d->vmode) == 16)
{
if (d->one_operand_p)
@@ -18328,7 +18602,8 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
memset (remap, 0xff, sizeof (remap));
dremap = *d;
- if (GET_MODE_SIZE (d->vmode) == 8)
+ if (GET_MODE_SIZE (d->vmode) == 4
+ || GET_MODE_SIZE (d->vmode) == 8)
{
unsigned HOST_WIDE_INT h1, h2, h3, h4;
@@ -19076,7 +19351,8 @@ expand_vec_perm_2perm_pblendv (struct expand_vec_perm_d *d, bool two_insn)
else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
;
else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 16
- || GET_MODE_SIZE (vmode) == 8))
+ || GET_MODE_SIZE (vmode) == 8
+ || GET_MODE_SIZE (vmode) == 4))
;
else
return false;
@@ -19337,7 +19613,8 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
rtx (*gen) (rtx, rtx, rtx);
if (!TARGET_SSSE3 || (GET_MODE_SIZE (d->vmode) != 16
- && GET_MODE_SIZE (d->vmode) != 8))
+ && GET_MODE_SIZE (d->vmode) != 8
+ && GET_MODE_SIZE (d->vmode) != 4))
return false;
gcc_assert (!d->one_operand_p);
@@ -19346,6 +19623,10 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
switch (GET_MODE_SIZE (d->vmode))
{
+ case 4:
+ mode = V4QImode;
+ gen = gen_mmx_pshufbv4qi3;
+ break;
case 8:
mode = V8QImode;
gen = gen_mmx_pshufbv8qi3;
@@ -19832,6 +20113,26 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd)
return false;
break;
+ case E_V4QImode:
+ if (TARGET_SSSE3 && !TARGET_SLOW_PSHUFB)
+ return expand_vec_perm_pshufb2 (d);
+ else
+ {
+ if (d->testing_p)
+ break;
+ /* We need 2*log2(N)-1 operations to achieve odd/even
+ with interleave. */
+ t1 = gen_reg_rtx (V4QImode);
+ emit_insn (gen_mmx_punpckhbw_low (t1, d->op0, d->op1));
+ emit_insn (gen_mmx_punpcklbw_low (d->target, d->op0, d->op1));
+ if (odd)
+ t2 = gen_mmx_punpckhbw_low (d->target, d->target, t1);
+ else
+ t2 = gen_mmx_punpcklbw_low (d->target, d->target, t1);
+ emit_insn (t2);
+ }
+ break;
+
case E_V4HImode:
if (TARGET_SSE4_1)
return expand_vec_perm_even_odd_pack (d);
@@ -20021,6 +20322,7 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
{
unsigned elt = d->perm[0], nelt2 = d->nelt / 2;
machine_mode vmode = d->vmode;
+ rtx (*gen) (rtx, rtx, rtx);
unsigned char perm2[4];
rtx op0 = d->op0, dest;
bool ok;
@@ -20045,24 +20347,48 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
/* These are always implementable using standard shuffle patterns. */
gcc_unreachable ();
+ case E_V4QImode:
+ /* This can be implemented via interleave and pshuflw. */
+ if (d->testing_p)
+ return true;
+
+ if (elt >= nelt2)
+ {
+ gen = gen_mmx_punpckhbw_low;
+ elt -= nelt2;
+ }
+ else
+ gen = gen_mmx_punpcklbw_low;
+
+ dest = gen_reg_rtx (vmode);
+ emit_insn (gen (dest, op0, op0));
+ vmode = get_mode_wider_vector (vmode);
+ op0 = gen_lowpart (vmode, dest);
+
+ memset (perm2, elt, 2);
+ dest = gen_reg_rtx (vmode);
+ ok = expand_vselect (dest, op0, perm2, 2, d->testing_p);
+ gcc_assert (ok);
+
+ emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
+ return true;
+
case E_V8QImode:
- /* These can be implemented via interleave. We save one insn by
+ /* This can be implemented via interleave. We save one insn by
stopping once we have promoted to V2SImode and then use pshufd. */
if (d->testing_p)
return true;
do
{
- rtx dest;
- rtx (*gen) (rtx, rtx, rtx)
- = vmode == V8QImode ? gen_mmx_punpcklbw
- : gen_mmx_punpcklwd;
-
if (elt >= nelt2)
{
gen = vmode == V8QImode ? gen_mmx_punpckhbw
: gen_mmx_punpckhwd;
elt -= nelt2;
}
+ else
+ gen = vmode == V8QImode ? gen_mmx_punpcklbw
+ : gen_mmx_punpcklwd;
nelt2 /= 2;
dest = gen_reg_rtx (vmode);
@@ -20073,11 +20399,11 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
while (vmode != V2SImode);
memset (perm2, elt, 2);
- dest = gen_reg_rtx (V2SImode);
+ dest = gen_reg_rtx (vmode);
ok = expand_vselect (dest, op0, perm2, 2, d->testing_p);
gcc_assert (ok);
- if (!d->testing_p)
- emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
+
+ emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
return true;
case E_V8HImode:
@@ -20088,17 +20414,15 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
return true;
do
{
- rtx dest;
- rtx (*gen) (rtx, rtx, rtx)
- = vmode == V16QImode ? gen_vec_interleave_lowv16qi
- : gen_vec_interleave_lowv8hi;
-
if (elt >= nelt2)
{
gen = vmode == V16QImode ? gen_vec_interleave_highv16qi
: gen_vec_interleave_highv8hi;
elt -= nelt2;
}
+ else
+ gen = vmode == V16QImode ? gen_vec_interleave_lowv16qi
+ : gen_vec_interleave_lowv8hi;
nelt2 /= 2;
dest = gen_reg_rtx (vmode);
@@ -20109,11 +20433,11 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
while (vmode != V4SImode);
memset (perm2, elt, 4);
- dest = gen_reg_rtx (V4SImode);
+ dest = gen_reg_rtx (vmode);
ok = expand_vselect (dest, op0, perm2, 4, d->testing_p);
gcc_assert (ok);
- if (!d->testing_p)
- emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
+
+ emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
return true;
case E_V64QImode:
@@ -20594,6 +20918,10 @@ ix86_vectorize_vec_perm_const (machine_mode vmode, rtx target, rtx op0,
if (d.testing_p)
return true;
break;
+ case E_V4QImode:
+ if (!TARGET_SSE2)
+ return false;
+ break;
case E_V2DImode:
case E_V2DFmode:
if (!TARGET_SSE)
diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index a25769a..cbd430a 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -544,71 +544,83 @@ general_scalar_chain::compute_convert_gain ()
+= m * ix86_cost->int_store[2] - ix86_cost->sse_store[sse_cost_idx];
else if (MEM_P (src) && REG_P (dst))
igain += m * ix86_cost->int_load[2] - ix86_cost->sse_load[sse_cost_idx];
- else if (GET_CODE (src) == ASHIFT
- || GET_CODE (src) == ASHIFTRT
- || GET_CODE (src) == LSHIFTRT)
- {
- if (m == 2)
- {
- if (INTVAL (XEXP (src, 1)) >= 32)
- igain += ix86_cost->add;
- else
- igain += ix86_cost->shift_const;
- }
+ else
+ switch (GET_CODE (src))
+ {
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (m == 2)
+ {
+ if (INTVAL (XEXP (src, 1)) >= 32)
+ igain += ix86_cost->add;
+ else
+ igain += ix86_cost->shift_const;
+ }
- igain += ix86_cost->shift_const - ix86_cost->sse_op;
+ igain += ix86_cost->shift_const - ix86_cost->sse_op;
- if (CONST_INT_P (XEXP (src, 0)))
- igain -= vector_const_cost (XEXP (src, 0));
- }
- else if (GET_CODE (src) == PLUS
- || GET_CODE (src) == MINUS
- || GET_CODE (src) == IOR
- || GET_CODE (src) == XOR
- || GET_CODE (src) == AND)
- {
- igain += m * ix86_cost->add - ix86_cost->sse_op;
- /* Additional gain for andnot for targets without BMI. */
- if (GET_CODE (XEXP (src, 0)) == NOT
- && !TARGET_BMI)
- igain += m * ix86_cost->add;
-
- if (CONST_INT_P (XEXP (src, 0)))
- igain -= vector_const_cost (XEXP (src, 0));
- if (CONST_INT_P (XEXP (src, 1)))
- igain -= vector_const_cost (XEXP (src, 1));
- }
- 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) == ABS
- || GET_CODE (src) == SMAX
- || GET_CODE (src) == SMIN
- || GET_CODE (src) == UMAX
- || GET_CODE (src) == UMIN)
- {
- /* We do not have any conditional move cost, estimate it as a
- reg-reg move. Comparisons are costed as adds. */
- igain += m * (COSTS_N_INSNS (2) + ix86_cost->add);
- /* Integer SSE ops are all costed the same. */
- igain -= ix86_cost->sse_op;
- }
- else if (GET_CODE (src) == COMPARE)
- {
- /* Assume comparison cost is the same. */
- }
- else if (CONST_INT_P (src))
- {
- if (REG_P (dst))
- /* DImode can be immediate for TARGET_64BIT and SImode always. */
- igain += m * COSTS_N_INSNS (1);
- else if (MEM_P (dst))
- igain += (m * ix86_cost->int_store[2]
- - ix86_cost->sse_store[sse_cost_idx]);
- igain -= vector_const_cost (src);
- }
- else
- gcc_unreachable ();
+ if (CONST_INT_P (XEXP (src, 0)))
+ igain -= vector_const_cost (XEXP (src, 0));
+ break;
+
+ case AND:
+ case IOR:
+ case XOR:
+ case PLUS:
+ case MINUS:
+ igain += m * ix86_cost->add - ix86_cost->sse_op;
+ /* Additional gain for andnot for targets without BMI. */
+ if (GET_CODE (XEXP (src, 0)) == NOT
+ && !TARGET_BMI)
+ igain += m * ix86_cost->add;
+
+ if (CONST_INT_P (XEXP (src, 0)))
+ igain -= vector_const_cost (XEXP (src, 0));
+ if (CONST_INT_P (XEXP (src, 1)))
+ igain -= vector_const_cost (XEXP (src, 1));
+ break;
+
+ case NEG:
+ case NOT:
+ igain -= ix86_cost->sse_op + COSTS_N_INSNS (1);
+
+ if (GET_CODE (XEXP (src, 0)) != ABS)
+ {
+ igain += m * ix86_cost->add;
+ break;
+ }
+ /* FALLTHRU */
+
+ case ABS:
+ case SMAX:
+ case SMIN:
+ case UMAX:
+ case UMIN:
+ /* We do not have any conditional move cost, estimate it as a
+ reg-reg move. Comparisons are costed as adds. */
+ igain += m * (COSTS_N_INSNS (2) + ix86_cost->add);
+ /* Integer SSE ops are all costed the same. */
+ igain -= ix86_cost->sse_op;
+ break;
+
+ case COMPARE:
+ /* Assume comparison cost is the same. */
+ break;
+
+ case CONST_INT:
+ if (REG_P (dst))
+ /* DImode can be immediate for TARGET_64BIT and SImode always. */
+ igain += m * COSTS_N_INSNS (1);
+ else if (MEM_P (dst))
+ igain += (m * ix86_cost->int_store[2]
+ - ix86_cost->sse_store[sse_cost_idx]);
+ igain -= vector_const_cost (src);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
if (igain != 0 && dump_file)
{
@@ -1009,7 +1021,19 @@ general_scalar_chain::convert_insn (rtx_insn *insn)
case NEG:
src = XEXP (src, 0);
- convert_op (&src, insn);
+
+ if (GET_CODE (src) == ABS)
+ {
+ src = XEXP (src, 0);
+ convert_op (&src, insn);
+ subreg = gen_reg_rtx (vmode);
+ emit_insn_before (gen_rtx_SET (subreg,
+ gen_rtx_ABS (vmode, src)), insn);
+ src = subreg;
+ }
+ else
+ convert_op (&src, insn);
+
subreg = gen_reg_rtx (vmode);
emit_insn_before (gen_move_insn (subreg, CONST0_RTX (vmode)), insn);
src = gen_rtx_MINUS (vmode, subreg, src);
@@ -1042,9 +1066,10 @@ general_scalar_chain::convert_insn (rtx_insn *insn)
gcc_assert (REG_P (src) && GET_MODE (src) == DImode);
subreg = gen_rtx_SUBREG (V2DImode, src, 0);
- emit_insn_before (gen_vec_interleave_lowv2di (copy_rtx_if_shared (subreg),
- copy_rtx_if_shared (subreg),
- copy_rtx_if_shared (subreg)),
+ emit_insn_before (gen_vec_interleave_lowv2di
+ (copy_rtx_if_shared (subreg),
+ copy_rtx_if_shared (subreg),
+ copy_rtx_if_shared (subreg)),
insn);
dst = gen_rtx_REG (CCmode, FLAGS_REG);
src = gen_rtx_UNSPEC (CCmode, gen_rtvec (2, copy_rtx_if_shared (subreg),
@@ -1400,11 +1425,11 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
return false;
/* Fallthru. */
- case PLUS:
- case MINUS:
+ case AND:
case IOR:
case XOR:
- case AND:
+ case PLUS:
+ case MINUS:
if (!REG_P (XEXP (src, 1))
&& !MEM_P (XEXP (src, 1))
&& !CONST_INT_P (XEXP (src, 1)))
@@ -1413,18 +1438,32 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
if (GET_MODE (XEXP (src, 1)) != mode
&& !CONST_INT_P (XEXP (src, 1)))
return false;
+
+ /* Check for andnot case. */
+ if (GET_CODE (src) != AND
+ || GET_CODE (XEXP (src, 0)) != NOT)
+ break;
+
+ src = XEXP (src, 0);
+ /* FALLTHRU */
+
+ case NOT:
break;
+ case NEG:
+ /* Check for nabs case. */
+ if (GET_CODE (XEXP (src, 0)) != ABS)
+ break;
+
+ src = XEXP (src, 0);
+ /* FALLTHRU */
+
case ABS:
if ((mode == DImode && !TARGET_AVX512VL)
|| (mode == SImode && !TARGET_SSSE3))
return false;
break;
- case NEG:
- case NOT:
- break;
-
case REG:
return true;
@@ -1438,12 +1477,8 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
if (!REG_P (XEXP (src, 0))
&& !MEM_P (XEXP (src, 0))
- && !CONST_INT_P (XEXP (src, 0))
- /* Check for andnot case. */
- && (GET_CODE (src) != AND
- || GET_CODE (XEXP (src, 0)) != NOT
- || !REG_P (XEXP (XEXP (src, 0), 0))))
- return false;
+ && !CONST_INT_P (XEXP (src, 0)))
+ return false;
if (GET_MODE (XEXP (src, 0)) != mode
&& !CONST_INT_P (XEXP (src, 0)))
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index 0eccb54..7a35c46 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -2831,6 +2831,8 @@ ix86_option_override_internal (bool main_args_p,
if (ix86_indirect_branch != indirect_branch_keep)
SET_OPTION_IF_UNSET (opts, opts_set, flag_jump_tables, 0);
+ SET_OPTION_IF_UNSET (opts, opts_set, param_ira_consider_dup_in_all_alts, 0);
+
return true;
}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65fc307..51376fc 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -50,6 +50,8 @@ extern void ix86_reset_previous_fndecl (void);
extern bool ix86_using_red_zone (void);
+extern rtx ix86_gen_scratch_sse_rtx (machine_mode);
+
extern unsigned int ix86_regmode_natural_size (machine_mode);
#ifdef RTX_CODE
extern int standard_80387_constant_p (rtx);
@@ -256,6 +258,8 @@ extern void ix86_expand_mul_widen_hilo (rtx, rtx, rtx, bool, bool);
extern void ix86_expand_sse2_mulv4si3 (rtx, rtx, rtx);
extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx);
extern void ix86_expand_sse2_abs (rtx, rtx);
+extern bool ix86_expand_vector_init_duplicate (bool, machine_mode, rtx,
+ rtx);
/* In i386-c.c */
extern void ix86_target_macros (void);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a93128f..cff2690 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -21930,10 +21930,12 @@ ix86_stack_protect_fail (void)
After all, the relocation needed is the same as for the call insn.
Whether or not a particular assembler allows us to enter such, I
guess we'll have to see. */
+
int
asm_preferred_eh_data_format (int code, int global)
{
- if (flag_pic)
+ /* PE-COFF is effectively always -fPIC because of the .reloc section. */
+ if (flag_pic || TARGET_PECOFF)
{
int type = DW_EH_PE_sdata8;
if (!TARGET_64BIT
@@ -21942,9 +21944,11 @@ asm_preferred_eh_data_format (int code, int global)
type = DW_EH_PE_sdata4;
return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
}
+
if (ix86_cmodel == CM_SMALL
|| (ix86_cmodel == CM_MEDIUM && code))
return DW_EH_PE_udata4;
+
return DW_EH_PE_absptr;
}
@@ -23163,6 +23167,19 @@ ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
}
}
+/* Return a scratch register in MODE for vector load and store. */
+
+rtx
+ix86_gen_scratch_sse_rtx (machine_mode mode)
+{
+ if (TARGET_SSE)
+ return gen_rtx_REG (mode, (TARGET_64BIT
+ ? LAST_REX_SSE_REG
+ : LAST_SSE_REG));
+ else
+ return gen_reg_rtx (mode);
+}
+
/* Address space support.
This is not "far pointers" in the 16-bit sense, but an easy way
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 6e0340a..8c3eace 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -73,6 +73,15 @@ struct stringop_algs
{
const enum stringop_alg unknown_size;
const struct stringop_strategy {
+ /* Several older compilers delete the default constructor because of the
+ const entries (see PR100246). Manually specifying a CTOR works around
+ this issue. Since this header is used by code compiled with the C
+ compiler we must guard the addition. */
+#ifdef __cplusplus
+ stringop_strategy(int _max = -1, enum stringop_alg _alg = libcall,
+ int _noalign = false)
+ : max (_max), alg (_alg), noalign (_noalign) {}
+#endif
const int max;
const enum stringop_alg alg;
int noalign;
@@ -1007,7 +1016,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
- || (MODE) == V4QImode || (MODE) == V2HImode \
+ || (MODE) == V4QImode || (MODE) == V2HImode || (MODE) == V1SImode \
|| (MODE) == V2DImode || (MODE) == DFmode)
#define VALID_SSE_REG_MODE(MODE) \
@@ -1039,7 +1048,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
|| (MODE) == SImode || (MODE) == DImode \
|| (MODE) == CQImode || (MODE) == CHImode \
|| (MODE) == CSImode || (MODE) == CDImode \
- || (MODE) == V4QImode || (MODE) == V2HImode \
+ || (MODE) == V4QImode || (MODE) == V2HImode || (MODE) == V1SImode \
|| (TARGET_64BIT \
&& ((MODE) == TImode || (MODE) == CTImode \
|| (MODE) == TFmode || (MODE) == TCmode \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9b619e2..8b809c4 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8385,7 +8385,7 @@
(ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
(parallel [(set (match_dup 0)
- (div:SWIM248 (match_dup 2) (match_dup 3)))
+ (div:SWIM248 (match_dup 2) (match_dup 3)))
(set (match_dup 1)
(mod:SWIM248 (match_dup 2) (match_dup 3)))
(use (match_dup 1))
@@ -8518,7 +8518,7 @@
(umod:SI (match_dup 2) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
- && exact_log2 (UINTVAL (operands[3])) > 0"
+ && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
"#"
"&& reload_completed"
[(set (match_dup 1) (match_dup 2))
@@ -8599,10 +8599,10 @@
(umod:SI (match_operand:SI 2 "register_operand" "0")
(match_operand:SI 3 "const_int_operand" "n"))))
(set (match_operand:SI 0 "register_operand" "=r")
- (umod:SI (match_dup 2) (match_dup 3)))
+ (udiv:SI (match_dup 2) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
- && exact_log2 (UINTVAL (operands[3])) > 0"
+ && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
"#"
"&& reload_completed"
[(set (match_dup 1) (match_dup 2))
@@ -8661,6 +8661,31 @@
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
+;; Avoid sign-extension (using cdq) for constant numerators.
+(define_insn_and_split "*divmodsi4_const"
+ [(set (match_operand:SI 0 "register_operand" "=&a")
+ (div:SI (match_operand:SI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SI 1 "register_operand" "=&d")
+ (mod:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "!optimize_function_for_size_p (cfun)"
+ "#"
+ "reload_completed"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 1) (match_dup 4))
+ (parallel [(set (match_dup 0)
+ (div:SI (match_dup 0) (match_dup 3)))
+ (set (match_dup 1)
+ (mod:SI (match_dup 0) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
(define_expand "divmodqi4"
[(parallel [(set (match_operand:QI 0 "register_operand")
(div:QI
@@ -10305,6 +10330,50 @@
split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
})
+(define_insn_and_split "*nabs<dwi>2_doubleword"
+ [(set (match_operand:<DWI> 0 "register_operand")
+ (neg:<DWI>
+ (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
+ (lt (reg:CCGOC FLAGS_REG) (const_int 0))
+ (match_dup 2)
+ (match_dup 1)))
+ (set (match_dup 3)
+ (if_then_else:DWIH
+ (lt (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
@@ -10332,6 +10401,34 @@
operands[2] = gen_reg_rtx (<MODE>mode);
})
+(define_insn_and_split "*nabs<mode>2_1"
+ [(set (match_operand:SWI 0 "register_operand")
+ (neg:SWI
+ (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
+ (lt (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")
(absneg:TF (match_operand:TF 1 "register_operand")))]
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 5f105727..986b758 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -57,10 +57,13 @@
(define_mode_iterator MMXMODE24 [V4HI V2SI])
(define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
-;; All 32bit integer vector modes
+;; All 4-byte integer vector modes
+(define_mode_iterator V_32 [V4QI V2HI V1SI])
+
+;; 4-byte integer vector modes
(define_mode_iterator VI_32 [V4QI V2HI])
-;; All V2S* modes
+;; V2S* modes
(define_mode_iterator V2FI [V2SF V2SI])
;; Mapping from integer vector mode to mnemonic suffix
@@ -238,8 +241,8 @@
})
(define_expand "mov<mode>"
- [(set (match_operand:VI_32 0 "nonimmediate_operand")
- (match_operand:VI_32 1 "nonimmediate_operand"))]
+ [(set (match_operand:V_32 0 "nonimmediate_operand")
+ (match_operand:V_32 1 "nonimmediate_operand"))]
"TARGET_SSE2"
{
ix86_expand_vector_move (<MODE>mode, operands);
@@ -247,9 +250,9 @@
})
(define_insn "*mov<mode>_internal"
- [(set (match_operand:VI_32 0 "nonimmediate_operand"
+ [(set (match_operand:V_32 0 "nonimmediate_operand"
"=r ,m ,v,v,v,m,r,v")
- (match_operand:VI_32 1 "general_operand"
+ (match_operand:V_32 1 "general_operand"
"rmC,rC,C,v,m,v,v,r"))]
"TARGET_SSE2 &&
!(MEM_P (operands[0]) && MEM_P (operands[1]))"
@@ -304,8 +307,8 @@
;; For TARGET_64BIT we always round up to 8 bytes.
(define_insn "*push<mode>2_rex64"
- [(set (match_operand:VI_32 0 "push_operand" "=X,X")
- (match_operand:VI_32 1 "nonmemory_no_elim_operand" "rC,*v"))]
+ [(set (match_operand:V_32 0 "push_operand" "=X,X")
+ (match_operand:V_32 1 "nonmemory_no_elim_operand" "rC,*v"))]
"TARGET_SSE2 && TARGET_64BIT"
"@
push{q}\t%q1
@@ -314,8 +317,8 @@
(set_attr "mode" "DI")])
(define_insn "*push<mode>2"
- [(set (match_operand:VI_32 0 "push_operand" "=<,<")
- (match_operand:VI_32 1 "general_no_elim_operand" "rC*m,*v"))]
+ [(set (match_operand:V_32 0 "push_operand" "=<,<")
+ (match_operand:V_32 1 "general_no_elim_operand" "rC*m,*v"))]
"TARGET_SSE2 && !TARGET_64BIT"
"@
push{l}\t%1
@@ -324,20 +327,20 @@
(set_attr "mode" "SI")])
(define_split
- [(set (match_operand:VI_32 0 "push_operand")
- (match_operand:VI_32 1 "sse_reg_operand"))]
+ [(set (match_operand:V_32 0 "push_operand")
+ (match_operand:V_32 1 "sse_reg_operand"))]
"TARGET_SSE2 && reload_completed"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
(set (match_dup 0) (match_dup 1))]
{
- operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<VI_32:MODE>mode)));
+ operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<V_32:MODE>mode)));
/* Preserve memory attributes. */
operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
})
(define_expand "movmisalign<mode>"
- [(set (match_operand:VI_32 0 "nonimmediate_operand")
- (match_operand:VI_32 1 "nonimmediate_operand"))]
+ [(set (match_operand:V_32 0 "nonimmediate_operand")
+ (match_operand:V_32 1 "nonimmediate_operand"))]
"TARGET_SSE2"
{
ix86_expand_vector_move (<MODE>mode, operands);
@@ -2006,6 +2009,23 @@
(match_operand:DI 2 "nonmemory_operand")))]
"TARGET_MMX_WITH_SSE")
+(define_insn "mmx_<insn>v1si3"
+ [(set (match_operand:V1SI 0 "register_operand" "=x,Yw")
+ (any_lshift:V1SI
+ (match_operand:V1SI 1 "register_operand" "0,Yw")
+ (match_operand:DI 2 "nonmemory_operand" "xN,YwN")))]
+ "TARGET_SSE2"
+ "@
+ p<vshift>d\t{%2, %0|%0, %2}
+ vp<vshift>d\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sseishft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand")
+ (const_string "1")
+ (const_string "0")))
+ (set_attr "mode" "TI")])
+
(define_insn "<insn>v2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
(any_shift:V2HI
@@ -2362,6 +2382,18 @@
[(set_attr "type" "sse4arg")
(set_attr "mode" "TI")])
+(define_insn "mmx_ppermv32"
+ [(set (match_operand:V4QI 0 "register_operand" "=x")
+ (unspec:V4QI
+ [(match_operand:V4QI 1 "register_operand" "x")
+ (match_operand:V4QI 2 "register_operand" "x")
+ (match_operand:V16QI 3 "nonimmediate_operand" "xm")]
+ UNSPEC_XOP_PERMUTE))]
+ "TARGET_XOP"
+ "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+ [(set_attr "type" "sse4arg")
+ (set_attr "mode" "TI")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel integral logical operations
@@ -2550,6 +2582,23 @@
(set_attr "type" "mmxcvt,sselog,sselog")
(set_attr "mode" "DI,TI,TI")])
+(define_insn_and_split "mmx_punpckhbw_low"
+ [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
+ (vec_select:V4QI
+ (vec_concat:V8QI
+ (match_operand:V4QI 1 "register_operand" "0,Yw")
+ (match_operand:V4QI 2 "register_operand" "x,Yw"))
+ (parallel [(const_int 2) (const_int 6)
+ (const_int 3) (const_int 7)])))]
+ "TARGET_SSE2"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_mmx_punpck (operands, true); DONE;"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog")
+ (set_attr "mode" "TI")])
+
(define_insn_and_split "mmx_punpcklbw"
[(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
(vec_select:V8QI
@@ -2573,6 +2622,23 @@
(set_attr "type" "mmxcvt,sselog,sselog")
(set_attr "mode" "DI,TI,TI")])
+(define_insn_and_split "mmx_punpcklbw_low"
+ [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
+ (vec_select:V4QI
+ (vec_concat:V8QI
+ (match_operand:V4QI 1 "register_operand" "0,Yw")
+ (match_operand:V4QI 2 "register_operand" "x,Yw"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 1) (const_int 5)])))]
+ "TARGET_SSE2"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_mmx_punpck (operands, false); DONE;"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog")
+ (set_attr "mode" "TI")])
+
(define_insn_and_split "mmx_punpckhwd"
[(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
(vec_select:V4HI
@@ -2686,6 +2752,20 @@
(set_attr "prefix" "orig,orig,maybe_evex")
(set_attr "mode" "TI")])
+(define_insn "sse4_1_<code>v2qiv2hi2"
+ [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,Yw")
+ (any_extend:V2HI
+ (vec_select:V2QI
+ (match_operand:V4QI 1 "register_operand" "Yr,*x,Yw")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "TARGET_SSE4_1"
+ "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}"
+ [(set_attr "isa" "noavx,noavx,avx")
+ (set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "prefix" "orig,orig,maybe_evex")
+ (set_attr "mode" "TI")])
+
;; Pack/unpack vector modes
(define_mode_attr mmxpackmode
[(V4HI "V8QI") (V2SI "V4HI")])
@@ -2702,6 +2782,18 @@
DONE;
})
+(define_expand "vec_pack_trunc_v2hi"
+ [(match_operand:V4QI 0 "register_operand")
+ (match_operand:V2HI 1 "register_operand")
+ (match_operand:V2HI 2 "register_operand")]
+ "TARGET_SSE2"
+{
+ rtx op1 = gen_lowpart (V4QImode, operands[1]);
+ rtx op2 = gen_lowpart (V4QImode, operands[2]);
+ ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
+ DONE;
+})
+
(define_mode_attr mmxunpackmode
[(V8QI "V4HI") (V4HI "V2SI")])
@@ -2729,6 +2821,30 @@
"TARGET_MMX_WITH_SSE"
"ix86_expand_sse_unpack (operands[0], operands[1], true, true); DONE;")
+(define_expand "vec_unpacks_lo_v4qi"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "TARGET_SSE2"
+ "ix86_expand_sse_unpack (operands[0], operands[1], false, false); DONE;")
+
+(define_expand "vec_unpacks_hi_v4qi"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "TARGET_SSE2"
+ "ix86_expand_sse_unpack (operands[0], operands[1], false, true); DONE;")
+
+(define_expand "vec_unpacku_lo_v4qi"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "TARGET_SSE2"
+ "ix86_expand_sse_unpack (operands[0], operands[1], true, false); DONE;")
+
+(define_expand "vec_unpacku_hi_v4qi"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "TARGET_SSE2"
+ "ix86_expand_sse_unpack (operands[0], operands[1], true, true); DONE;")
+
(define_insn "*mmx_pinsrd"
[(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
(vec_merge:V2SI
@@ -2930,6 +3046,24 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "TI")])
+(define_insn "mmx_pshufbv4qi3"
+ [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
+ (unspec:V4QI
+ [(match_operand:V4QI 1 "register_operand" "0,Yw")
+ (match_operand:V16QI 2 "vector_operand" "xBm,Ywm")]
+ UNSPEC_PSHUFB))]
+ "TARGET_SSSE3"
+ "@
+ pshufb\t{%2, %0|%0, %2}
+ vpshufb\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog1")
+ (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_extra" "1")
+ (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "btver2_decode" "vector")
+ (set_attr "mode" "TI")])
+
(define_expand "mmx_pshufw"
[(match_operand:V4HI 0 "register_operand")
(match_operand:V4HI 1 "register_mmxmem_operand")
@@ -3002,12 +3136,12 @@
(set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
-(define_insn "*mmx_pblendw"
+(define_insn "*mmx_pblendw64"
[(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,x")
(vec_merge:V4HI
(match_operand:V4HI 2 "register_operand" "Yr,*x,x")
(match_operand:V4HI 1 "register_operand" "0,0,x")
- (match_operand:SI 3 "const_0_to_63_operand" "n,n,n")))]
+ (match_operand:SI 3 "const_0_to_15_operand" "n,n,n")))]
"TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
"@
pblendw\t{%3, %2, %0|%0, %2, %3}
@@ -3020,6 +3154,24 @@
(set_attr "prefix" "orig,orig,vex")
(set_attr "mode" "TI")])
+(define_insn "*mmx_pblendw32"
+ [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,x")
+ (vec_merge:V2HI
+ (match_operand:V2HI 2 "register_operand" "Yr,*x,x")
+ (match_operand:V2HI 1 "register_operand" "0,0,x")
+ (match_operand:SI 3 "const_0_to_7_operand" "n,n,n")))]
+ "TARGET_SSE4_1"
+ "@
+ pblendw\t{%3, %2, %0|%0, %2, %3}
+ pblendw\t{%3, %2, %0|%0, %2, %3}
+ vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+ [(set_attr "isa" "noavx,noavx,avx")
+ (set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,orig,vex")
+ (set_attr "mode" "TI")])
+
;; Optimize V2SImode load from memory, swapping the elements and
;; storing back into the memory into DImode rotate of the memory by 32.
(define_split
@@ -3452,11 +3604,14 @@
(define_expand "vec_setv2hi"
[(match_operand:V2HI 0 "register_operand")
(match_operand:HI 1 "register_operand")
- (match_operand 2 "const_int_operand")]
+ (match_operand 2 "vec_setm_operand")]
"TARGET_SSE2"
{
- 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;
})
@@ -3474,11 +3629,14 @@
(define_expand "vec_setv4qi"
[(match_operand:V4QI 0 "register_operand")
(match_operand:QI 1 "register_operand")
- (match_operand 2 "const_int_operand")]
+ (match_operand 2 "vec_setm_mmx_operand")]
"TARGET_SSE4_1"
{
- 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;
})
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index e7a8968..9488632 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -145,16 +145,16 @@
unsigned HOST_WIDE_INT val = TARGET_64BIT ? 0xfa1e0ff3 : 0xfb1e0ff3;
if (imm == val)
- return 1;
+ return true;
/* NB: Encoding is byte based. */
if (TARGET_64BIT)
for (; imm >= val; imm >>= 8)
if (imm == val)
- return 1;
+ return true;
}
- return 0;
+ return false;
})
;; Return true if VALUE can be stored in a sign extended immediate field.
@@ -1023,7 +1023,7 @@
;; 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_test "TARGET_SSE4_1"))
(match_code "const_int")))
(define_predicate "vec_setm_mmx_operand"
@@ -1559,15 +1559,15 @@
unsigned HOST_WIDE_INT ei;
if (!CONST_INT_P (er))
- return 0;
+ return false;
ei = INTVAL (er);
if (i < nelt2 && ei != i)
- return 0;
+ return false;
if (i >= nelt2 && (ei < nelt || ei >= nelt << 1))
- return 0;
+ return false;
}
- return 1;
+ return true;
})
;; Return true if OP is a vzeroall operation, known to be a PARALLEL.
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index d3f5a74..17c9e57 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -4644,6 +4644,25 @@
;;
;; But this doesn't seem useful in practice.
+(define_expand "vec_fmaddsub<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (unspec:VF
+ [(match_operand:VF 1 "nonimmediate_operand")
+ (match_operand:VF 2 "nonimmediate_operand")
+ (match_operand:VF 3 "nonimmediate_operand")]
+ UNSPEC_FMADDSUB))]
+ "TARGET_FMA || TARGET_FMA4 || (<MODE_SIZE> == 64 || TARGET_AVX512VL)")
+
+(define_expand "vec_fmsubadd<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (unspec:VF
+ [(match_operand:VF 1 "nonimmediate_operand")
+ (match_operand:VF 2 "nonimmediate_operand")
+ (neg:VF
+ (match_operand:VF 3 "nonimmediate_operand"))]
+ UNSPEC_FMADDSUB))]
+ "TARGET_FMA || TARGET_FMA4 || (<MODE_SIZE> == 64 || TARGET_AVX512VL)")
+
(define_expand "fmaddsub_<mode>"
[(set (match_operand:VF 0 "register_operand")
(unspec:VF
@@ -11199,12 +11218,14 @@
(define_mode_iterator PMOV_SRC_MODE_4 [V4DI V2DI V4SI])
(define_mode_attr pmov_dst_4
[(V4DI "V4HI") (V2DI "V2HI") (V4SI "V4HI")])
+(define_mode_attr pmov_dst_4_lower
+ [(V4DI "v4hi") (V2DI "v2hi") (V4SI "v4hi")])
(define_mode_attr pmov_dst_zeroed_4
[(V4DI "V4HI") (V2DI "V6HI") (V4SI "V4HI")])
(define_mode_attr pmov_suff_4
[(V4DI "qw") (V2DI "qw") (V4SI "dw")])
-(define_expand "trunc<mode><pmov_dst_4>2"
+(define_expand "trunc<mode><pmov_dst_4_lower>2"
[(set (match_operand:<pmov_dst_4> 0 "register_operand")
(truncate:<pmov_dst_4>
(match_operand:PMOV_SRC_MODE_4 1 "register_operand")))]
@@ -24814,3 +24835,34 @@
"TARGET_WIDEKL"
"aes<aeswideklvariant>\t{%0}"
[(set_attr "type" "other")])
+
+;; Modes handled by broadcast patterns. NB: Allow V64QI and V32HI with
+;; TARGET_AVX512F since ix86_expand_vector_init_duplicate can expand
+;; without TARGET_AVX512BW which is used by memset vector broadcast
+;; expander to XI with:
+;; vmovd %edi, %xmm15
+;; vpbroadcastb %xmm15, %ymm15
+;; vinserti64x4 $0x1, %ymm15, %zmm15, %zmm15
+
+(define_mode_iterator INT_BROADCAST_MODE
+ [(V64QI "TARGET_AVX512F") (V32QI "TARGET_AVX") V16QI
+ (V32HI "TARGET_AVX512F") (V16HI "TARGET_AVX") V8HI
+ (V16SI "TARGET_AVX512F") (V8SI "TARGET_AVX") V4SI
+ (V8DI "TARGET_AVX512F && TARGET_64BIT")
+ (V4DI "TARGET_AVX && TARGET_64BIT") (V2DI "TARGET_64BIT")])
+
+;; Broadcast from an integer. NB: Enable broadcast only if we can move
+;; from GPR to SSE register directly.
+(define_expand "vec_duplicate<mode>"
+ [(set (match_operand:INT_BROADCAST_MODE 0 "register_operand")
+ (vec_duplicate:INT_BROADCAST_MODE
+ (match_operand:<ssescalarmode> 1 "nonimmediate_operand")))]
+ "TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
+{
+ if (!ix86_expand_vector_init_duplicate (false,
+ GET_MODE (operands[0]),
+ operands[0],
+ operands[1]))
+ gcc_unreachable ();
+ DONE;
+})
diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h
index 23313fb..82b2c70 100644
--- a/gcc/config/m32r/m32r-protos.h
+++ b/gcc/config/m32r/m32r-protos.h
@@ -49,13 +49,13 @@ extern rtx m32r_return_addr (int);
extern rtx m32r_function_symbol (const char *);
#ifdef HAVE_MACHINE_MODES
-extern int call_operand (rtx, machine_mode);
-extern int small_data_operand (rtx, machine_mode);
+extern bool call_operand (rtx, machine_mode);
+extern bool small_data_operand (rtx, machine_mode);
extern int addr24_operand (rtx, machine_mode);
extern int addr32_operand (rtx, machine_mode);
extern int call26_operand (rtx, machine_mode);
-extern int memreg_operand (rtx, machine_mode);
-extern int small_insn_p (rtx, machine_mode);
+extern bool memreg_operand (rtx, machine_mode);
+extern bool small_insn_p (rtx, machine_mode);
#endif /* HAVE_MACHINE_MODES */
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 3444ed4..1aaba94 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -532,7 +532,7 @@ m32r_init_expanders (void)
to make it easy to experiment. */
}
-int
+bool
call_operand (rtx op, machine_mode mode)
{
if (!MEM_P (op))
@@ -543,7 +543,7 @@ call_operand (rtx op, machine_mode mode)
/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
-int
+bool
small_data_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
{
if (! TARGET_SDATA_USE)
@@ -674,7 +674,7 @@ easy_df_const (rtx op)
/* Return 1 if OP is (mem (reg ...)).
This is used in insn length calcs. */
-int
+bool
memreg_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
{
return MEM_P (op) && REG_P (XEXP (op, 0));
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 2cf4ed5..51b82b1 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -366,7 +366,7 @@ extern bool umips_12bit_offset_address_p (rtx, machine_mode);
extern bool mips_9bit_offset_address_p (rtx, machine_mode);
extern bool lwsp_swsp_address_p (rtx, machine_mode);
extern bool m16_based_address_p (rtx, machine_mode,
- int (*)(rtx_def*, machine_mode));
+ bool (*)(rtx_def*, machine_mode));
extern rtx mips_expand_thread_pointer (rtx);
extern void mips16_expand_get_fcsr (rtx);
extern void mips16_expand_set_fcsr (rtx);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 1f1475c..00a8eef 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2879,7 +2879,7 @@ mips_const_insns (rtx x)
return mips_build_integer (codes, INTVAL (x));
case CONST_VECTOR:
- if (ISA_HAS_MSA
+ if (MSA_SUPPORTED_MODE_P (GET_MODE (x))
&& mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511))
return 1;
/* Fall through. */
@@ -21732,7 +21732,7 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
rtx (*cmpFunc) (rtx, rtx, rtx);
rtx tmp, dest, zero;
- if (ISA_HAS_MSA)
+ if (MSA_SUPPORTED_MODE_P (imode))
{
switch (imode)
{
@@ -21994,7 +21994,7 @@ mips_expand_vector_init (rtx target, rtx vals)
all_same = false;
}
- if (ISA_HAS_MSA)
+ if (MSA_SUPPORTED_MODE_P (vmode))
{
if (all_same)
{
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index d7ce4de..a0dfefc 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -484,6 +484,25 @@
| RS6000_BTC_SENARY), \
CODE_FOR_ ## ICODE) /* ICODE */
+#define BU_MMA_PAIR_LD(ENUM, NAME, ATTR) \
+ RS6000_BUILTIN_M (VSX_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_vsx_" NAME, /* NAME */ \
+ RS6000_BTM_MMA, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY \
+ | RS6000_BTC_GIMPLE), \
+ CODE_FOR_nothing) /* ICODE */
+
+#define BU_MMA_PAIR_ST(ENUM, NAME, ATTR) \
+ RS6000_BUILTIN_M (VSX_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_vsx_" NAME, /* NAME */ \
+ RS6000_BTM_MMA, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_TERNARY \
+ | RS6000_BTC_VOID \
+ | RS6000_BTC_GIMPLE), \
+ CODE_FOR_nothing) /* ICODE */
+
/* ISA 2.05 (power6) convenience macros. */
/* For functions that depend on the CMPB instruction */
#define BU_P6_2(ENUM, NAME, ATTR, ICODE) \
@@ -3012,10 +3031,10 @@ BU_P10V_AV_2 (DIVS_V4SI, "vdivsw", CONST, divv4si3)
BU_P10V_AV_2 (DIVS_V2DI, "vdivsd", CONST, divv2di3)
BU_P10V_AV_2 (DIVU_V4SI, "vdivuw", CONST, udivv4si3)
BU_P10V_AV_2 (DIVU_V2DI, "vdivud", CONST, udivv2di3)
-BU_P10V_AV_2 (MODS_V2DI, "vmodsd", CONST, mods_v2di)
-BU_P10V_AV_2 (MODS_V4SI, "vmodsw", CONST, mods_v4si)
-BU_P10V_AV_2 (MODU_V2DI, "vmodud", CONST, modu_v2di)
-BU_P10V_AV_2 (MODU_V4SI, "vmoduw", CONST, modu_v4si)
+BU_P10V_AV_2 (MODS_V2DI, "vmodsd", CONST, modv2di3)
+BU_P10V_AV_2 (MODS_V4SI, "vmodsw", CONST, modv4si3)
+BU_P10V_AV_2 (MODU_V2DI, "vmodud", CONST, umodv2di3)
+BU_P10V_AV_2 (MODU_V4SI, "vmoduw", CONST, umodv4si3)
BU_P10V_AV_2 (MULHS_V2DI, "vmulhsd", CONST, mulhs_v2di)
BU_P10V_AV_2 (MULHS_V4SI, "vmulhsw", CONST, mulhs_v4si)
BU_P10V_AV_2 (MULHU_V2DI, "vmulhud", CONST, mulhu_v2di)
@@ -3253,6 +3272,9 @@ BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
BU_P10V_VSX_1 (XVCVBF16SPN, "xvcvbf16spn", MISC, vsx_xvcvbf16spn)
BU_P10V_VSX_1 (XVCVSPBF16, "xvcvspbf16", MISC, vsx_xvcvspbf16)
+BU_MMA_PAIR_LD (LXVP, "lxvp", MISC)
+BU_MMA_PAIR_ST (STXVP, "stxvp", PAIR)
+
BU_MMA_1 (XXMFACC, "xxmfacc", QUAD, mma_xxmfacc)
BU_MMA_1 (XXMTACC, "xxmtacc", QUAD, mma_xxmtacc)
BU_MMA_1 (XXSETACCZ, "xxsetaccz", MISC, mma_xxsetaccz)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b677898..904e104 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -11913,6 +11913,32 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
gsi_replace_with_seq (gsi, new_seq, true);
return true;
}
+ else if (fncode == VSX_BUILTIN_LXVP)
+ {
+ push_gimplify_context (true);
+ tree offset = gimple_call_arg (stmt, 0);
+ tree ptr = gimple_call_arg (stmt, 1);
+ tree lhs = gimple_call_lhs (stmt);
+ tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (ptr), ptr, offset));
+ gimplify_assign (lhs, mem, &new_seq);
+ pop_gimplify_context (NULL);
+ gsi_replace_with_seq (gsi, new_seq, true);
+ return true;
+ }
+ else if (fncode == VSX_BUILTIN_STXVP)
+ {
+ push_gimplify_context (true);
+ tree src = gimple_call_arg (stmt, 0);
+ tree offset = gimple_call_arg (stmt, 1);
+ tree ptr = gimple_call_arg (stmt, 2);
+ tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (ptr), ptr, offset));
+ gimplify_assign (mem, src, &new_seq);
+ pop_gimplify_context (NULL);
+ gsi_replace_with_seq (gsi, new_seq, true);
+ return true;
+ }
/* Convert this built-in into an internal version that uses pass-by-value
arguments. The internal built-in follows immediately after this one. */
@@ -14264,11 +14290,15 @@ mma_init_builtins (void)
if (gimple_func)
{
gcc_assert (icode == CODE_FOR_nothing);
- op[nopnds++] = void_type_node;
/* Some MMA built-ins that are expanded into gimple are converted
into internal MMA built-ins that are expanded into rtl.
The internal built-in follows immediately after this built-in. */
- icode = d[1].icode;
+ if (d->code != VSX_BUILTIN_LXVP
+ && d->code != VSX_BUILTIN_STXVP)
+ {
+ op[nopnds++] = void_type_node;
+ icode = d[1].icode;
+ }
}
else
{
@@ -14291,6 +14321,19 @@ mma_init_builtins (void)
else
op[nopnds++] = build_pointer_type (vector_pair_type_node);
}
+ else if (d->code == VSX_BUILTIN_LXVP)
+ {
+ op[nopnds++] = vector_pair_type_node;
+ op[nopnds++] = sizetype;
+ op[nopnds++] = build_pointer_type (vector_pair_type_node);
+ }
+ else if (d->code == VSX_BUILTIN_STXVP)
+ {
+ op[nopnds++] = void_type_node;
+ op[nopnds++] = vector_pair_type_node;
+ op[nopnds++] = sizetype;
+ op[nopnds++] = build_pointer_type (vector_pair_type_node);
+ }
else
{
/* This is a normal MMA built-in function. */
@@ -14781,6 +14824,16 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
h.uns_p[2] = 1;
break;
+ case VSX_BUILTIN_LXVP:
+ h.uns_p[0] = 1;
+ h.uns_p[2] = 1;
+ break;
+
+ case VSX_BUILTIN_STXVP:
+ h.uns_p[1] = 1;
+ h.uns_p[3] = 1;
+ break;
+
default:
break;
}
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 075c156..9a5db63 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1146,7 +1146,7 @@ static bool set_to_load_agen (rtx_insn *,rtx_insn *);
static bool insn_terminates_group_p (rtx_insn *, enum group_termination);
static bool insn_must_be_first_in_group (rtx_insn *);
static bool insn_must_be_last_in_group (rtx_insn *);
-int easy_vector_constant (rtx, machine_mode);
+bool easy_vector_constant (rtx, machine_mode);
static rtx rs6000_debug_legitimize_address (rtx, rtx, machine_mode);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
#if TARGET_MACHO
@@ -15699,8 +15699,8 @@ rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
return 1;
}
-/* Possibly emit the xsmaxcdp and xsmincdp instructions to emit a maximum or
- minimum with "C" semantics.
+/* Possibly emit the xsmaxc{dp,qp} and xsminc{dp,qp} instructions to emit a
+ maximum or minimum with "C" semantics.
Unless you use -ffast-math, you can't use these instructions to replace
conditions that implicitly reverse the condition because the comparison
@@ -15776,6 +15776,7 @@ rs6000_maybe_emit_fp_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
enum rtx_code code = GET_CODE (op);
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
+ machine_mode compare_mode = GET_MODE (op0);
machine_mode result_mode = GET_MODE (dest);
rtx compare_rtx;
rtx cmove_rtx;
@@ -15784,6 +15785,29 @@ rs6000_maybe_emit_fp_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
if (!can_create_pseudo_p ())
return 0;
+ /* We allow the comparison to be either SFmode/DFmode and the true/false
+ condition to be either SFmode/DFmode. I.e. we allow:
+
+ float a, b;
+ double c, d, r;
+
+ r = (a == b) ? c : d;
+
+ and:
+
+ double a, b;
+ float c, d, r;
+
+ r = (a == b) ? c : d;
+
+ but we don't allow intermixing the IEEE 128-bit floating point types with
+ the 32/64-bit scalar types. */
+
+ if (!(compare_mode == result_mode
+ || (compare_mode == SFmode && result_mode == DFmode)
+ || (compare_mode == DFmode && result_mode == SFmode)))
+ return false;
+
switch (code)
{
case EQ:
@@ -15836,6 +15860,10 @@ have_compare_and_set_mask (machine_mode mode)
case E_DFmode:
return TARGET_P9_MINMAX;
+ case E_KFmode:
+ case E_TFmode:
+ return TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode);
+
default:
break;
}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index abd825f..2368153 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3234,6 +3234,14 @@
[(set_attr "type" "div")
(set_attr "size" "<bits>")])
+(define_insn "udivti3"
+ [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+ (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
+ (match_operand:TI 2 "altivec_register_operand" "v")))]
+ "TARGET_POWER10 && TARGET_POWERPC64"
+ "vdivuq %0,%1,%2"
+ [(set_attr "type" "vecdiv")
+ (set_attr "size" "128")])
;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
;; modulus. If it isn't a power of two, force operands into register and do
@@ -3324,6 +3332,15 @@
(set_attr "length" "8,12")
(set_attr "cell_micro" "not")])
+(define_insn "divti3"
+ [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+ (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
+ (match_operand:TI 2 "altivec_register_operand" "v")))]
+ "TARGET_POWER10 && TARGET_POWERPC64"
+ "vdivsq %0,%1,%2"
+ [(set_attr "type" "vecdiv")
+ (set_attr "size" "128")])
+
(define_expand "mod<mode>3"
[(set (match_operand:GPR 0 "gpc_reg_operand")
(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
@@ -3424,6 +3441,23 @@
(minus:GPR (match_dup 1)
(match_dup 3)))])
+(define_insn "umodti3"
+ [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+ (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
+ (match_operand:TI 2 "altivec_register_operand" "v")))]
+ "TARGET_POWER10 && TARGET_POWERPC64"
+ "vmoduq %0,%1,%2"
+ [(set_attr "type" "vecdiv")
+ (set_attr "size" "128")])
+
+(define_insn "modti3"
+ [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+ (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
+ (match_operand:TI 2 "altivec_register_operand" "v")))]
+ "TARGET_POWER10 && TARGET_POWERPC64"
+ "vmodsq %0,%1,%2"
+ [(set_attr "type" "vecdiv")
+ (set_attr "size" "128")])
;; Logical instructions
;; The logical instructions are mostly combined by using match_operator,
@@ -5449,6 +5483,112 @@
"xxsel %x0,%x4,%x3,%x1"
[(set_attr "type" "vecmove")])
+;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the
+;; comparison must be the same as used in the move.
+(define_expand "mov<mode>cc"
+ [(set (match_operand:IEEE128 0 "gpc_reg_operand")
+ (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
+ (match_operand:IEEE128 2 "gpc_reg_operand")
+ (match_operand:IEEE128 3 "gpc_reg_operand")))]
+ "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+{
+ if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
+ DONE;
+ else
+ FAIL;
+})
+
+(define_insn_and_split "*mov<mode>cc_p10"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
+ (if_then_else:IEEE128
+ (match_operator:CCFP 1 "fpmask_comparison_operator"
+ [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
+ (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
+ (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
+ (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
+ (clobber (match_scratch:V2DI 6 "=0,&v"))]
+ "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (if_then_else:V2DI (match_dup 1)
+ (match_dup 7)
+ (match_dup 8)))
+ (set (match_dup 0)
+ (if_then_else:IEEE128 (ne (match_dup 6)
+ (match_dup 8))
+ (match_dup 4)
+ (match_dup 5)))]
+{
+ if (GET_CODE (operands[6]) == SCRATCH)
+ operands[6] = gen_reg_rtx (V2DImode);
+
+ operands[7] = CONSTM1_RTX (V2DImode);
+ operands[8] = CONST0_RTX (V2DImode);
+}
+ [(set_attr "length" "8")
+ (set_attr "type" "vecperm")])
+
+;; Handle inverting the fpmask comparisons.
+(define_insn_and_split "*mov<mode>cc_invert_p10"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
+ (if_then_else:IEEE128
+ (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
+ [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
+ (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
+ (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
+ (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
+ (clobber (match_scratch:V2DI 6 "=0,&v"))]
+ "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "#"
+ "&& 1"
+ [(set (match_dup 6)
+ (if_then_else:V2DI (match_dup 9)
+ (match_dup 7)
+ (match_dup 8)))
+ (set (match_dup 0)
+ (if_then_else:IEEE128 (ne (match_dup 6)
+ (match_dup 8))
+ (match_dup 5)
+ (match_dup 4)))]
+{
+ rtx op1 = operands[1];
+ enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
+
+ if (GET_CODE (operands[6]) == SCRATCH)
+ operands[6] = gen_reg_rtx (V2DImode);
+
+ operands[7] = CONSTM1_RTX (V2DImode);
+ operands[8] = CONST0_RTX (V2DImode);
+
+ operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
+}
+ [(set_attr "length" "8")
+ (set_attr "type" "vecperm")])
+
+(define_insn "*fpmask<mode>"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (if_then_else:V2DI
+ (match_operator:CCFP 1 "fpmask_comparison_operator"
+ [(match_operand:IEEE128 2 "altivec_register_operand" "v")
+ (match_operand:IEEE128 3 "altivec_register_operand" "v")])
+ (match_operand:V2DI 4 "all_ones_constant" "")
+ (match_operand:V2DI 5 "zero_constant" "")))]
+ "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xscmp%V1qp %0,%2,%3"
+ [(set_attr "type" "fpcompare")])
+
+(define_insn "*xxsel<mode>"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (if_then_else:IEEE128
+ (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
+ (match_operand:V2DI 2 "zero_constant" ""))
+ (match_operand:IEEE128 3 "altivec_register_operand" "v")
+ (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
+ "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xxsel %x0,%x4,%x3,%x1"
+ [(set_attr "type" "vecmove")])
+
;; Conversions to and from floating-point.
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index f2260ba..f622873 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -6333,7 +6333,7 @@
[(set_attr "type" "vecdiv")
(set_attr "size" "<bits>")])
-(define_insn "mods_<mode>"
+(define_insn "mod<mode>3"
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
(mod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
@@ -6342,7 +6342,7 @@
[(set_attr "type" "vecdiv")
(set_attr "size" "<bits>")])
-(define_insn "modu_<mode>"
+(define_insn "umod<mode>3"
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
(umod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
diff --git a/gcc/config/stormy16/stormy16-protos.h b/gcc/config/stormy16/stormy16-protos.h
index c81ea8c..d8010af 100644
--- a/gcc/config/stormy16/stormy16-protos.h
+++ b/gcc/config/stormy16/stormy16-protos.h
@@ -54,7 +54,7 @@ extern void xstormy16_expand_andqi3 (rtx *);
#if defined (HAVE_MACHINE_MODES) && defined (RTX_CODE)
extern void xstormy16_split_cbranch (machine_mode, rtx, rtx, rtx);
extern int short_memory_operand (rtx, machine_mode);
-extern int nonimmediate_nonstack_operand (rtx, machine_mode);
+extern bool nonimmediate_nonstack_operand (rtx, machine_mode);
extern enum reg_class xstormy16_secondary_reload_class
(enum reg_class, machine_mode, rtx);
extern void xstormy16_split_move (machine_mode, rtx, rtx);
@@ -63,8 +63,8 @@ extern void xstormy16_expand_arith (machine_mode, enum rtx_code,
rtx, rtx, rtx);
extern const char * xstormy16_output_shift (machine_mode, enum rtx_code,
rtx, rtx, rtx);
-extern int xstormy16_below100_symbol (rtx, machine_mode);
-extern int xstormy16_splittable_below100_operand (rtx, machine_mode);
+extern bool xstormy16_below100_symbol (rtx, machine_mode);
+extern bool xstormy16_splittable_below100_operand (rtx, machine_mode);
extern bool xstormy16_legitimate_address_p (machine_mode, rtx, bool);
#endif
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index fb7670f..92011fd 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -516,7 +516,7 @@ xstormy16_preferred_reload_class (rtx x, reg_class_t rclass)
/* Predicate for symbols and addresses that reflect special 8-bit
addressing. */
-int
+bool
xstormy16_below100_symbol (rtx x,
machine_mode mode ATTRIBUTE_UNUSED)
{
@@ -542,7 +542,7 @@ xstormy16_below100_symbol (rtx x,
/* Likewise, but only for non-volatile MEMs, for patterns where the
MEM will get split into smaller sized accesses. */
-int
+bool
xstormy16_splittable_below100_operand (rtx x, machine_mode mode)
{
if (MEM_P (x) && MEM_VOLATILE_P (x))
diff --git a/gcc/configure b/gcc/configure
index f0b2ebd..a15f8b4 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -723,6 +723,8 @@ thin_archive_support
ld_soname_option
ld_version_script_option
libgcc_visibility
+ORIGINAL_DSYMUTIL_FOR_TARGET
+gcc_cv_dsymutil
gcc_cv_otool
gcc_cv_readelf
gcc_cv_objdump
@@ -946,6 +948,7 @@ enable_generated_files_in_srcdir
with_gnu_ld
with_ld
with_demangler_in_ld
+with_dsymutil
with_gnu_as
with_as
enable_largefile
@@ -1813,6 +1816,8 @@ Optional Packages:
--with-gnu-ld arrange to work with GNU ld
--with-ld arrange to use the specified ld (full pathname)
--with-demangler-in-ld try to use demangler in GNU ld
+ --with-dsymutil arrange to use the specified dsymutil (full
+ pathname)
--with-gnu-as arrange to work with GNU as
--with-as arrange to use the specified as (full pathname)
--with-stabs arrange to use stabs instead of host debug format
@@ -3835,8 +3840,14 @@ fi
case $target in
- *darwin*) ld64_flag=yes;; # Darwin can only use a ld64-compatible linker.
- *) ld64_flag=no;;
+ *darwin*)
+ ld64_flag=yes # Darwin can only use a ld64-compatible linker.
+ dsymutil_flag=yes # Darwin uses dsymutil to link debug.
+ ;;
+ *)
+ ld64_flag=no
+ dsymutil_flag=no
+ ;;
esac
# With pre-defined ld
@@ -3886,6 +3897,40 @@ else
fi
+# Allow the user to specify a dsymutil executable (used on Darwin only, so far)
+
+# Check whether --with-dsymutil was given.
+if test "${with_dsymutil+set}" = set; then :
+ withval=$with_dsymutil; DEFAULT_DSYMUTIL="$with_dsymutil"
+fi
+
+
+dsymutil_vers=
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+ if test ! -x "$DEFAULT_DSYMUTIL"; then
+ as_fn_error $? "cannot execute: $DEFAULT_DSYMUTIL: check --with-dsymutil or env. var. DEFAULT_DSYMUTIL" "$LINENO" 5
+ else
+ if dsymutil_vers=`$DEFAULT_DSYMUTIL -v /dev/null 2>&1`; then
+ dsymutil_flag=yes
+ fi
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_DSYMUTIL "$DEFAULT_DSYMUTIL"
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a default dsymutil was specified" >&5
+$as_echo_n "checking whether a default dsymutil was specified... " >&6; }
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_DSYMUTIL)" >&5
+$as_echo "yes ($DEFAULT_DSYMUTIL)" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
# ----------------------
# Find default assembler
# ----------------------
@@ -19435,7 +19480,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19438 "configure"
+#line 19483 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19541,7 +19586,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19544 "configure"
+#line 19589 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -23439,6 +23484,71 @@ else
$as_echo "$gcc_cv_otool" >&6; }
fi
+# Figure out the dsymutil we will use.
+if ${gcc_cv_dsymutil+:} false; then :
+
+else
+
+if test -x "$DEFAULT_DSYMUTIL"; then
+ gcc_cv_dsymutil="$DEFAULT_DSYMUTIL"
+elif test -x dsymutil$build_exeext; then
+ gcc_cv_dsymutil=./dsymutil$build_exeext
+elif ( set dummy $DSYMUTIL_FOR_TARGET; test -x $2 ); then
+ gcc_cv_dsymutil=$DSYMUTIL_FOR_TARGET
+elif ( set dummy $DSYMUTIL; test -x $2 ); then
+ gcc_cv_dsymutil=$DSYMUTIL
+else
+ # Extract the first word of "$DSYMUTIL_FOR_TARGET", so it can be a program name with args.
+set dummy $DSYMUTIL_FOR_TARGET; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_gcc_cv_dsymutil+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $gcc_cv_dsymutil in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_gcc_cv_dsymutil="$gcc_cv_dsymutil" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_gcc_cv_dsymutil="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+gcc_cv_dsymutil=$ac_cv_path_gcc_cv_dsymutil
+if test -n "$gcc_cv_dsymutil"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_dsymutil" >&5
+$as_echo "$gcc_cv_dsymutil" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+fi
+
+ORIGINAL_DSYMUTIL_FOR_TARGET=$gcc_cv_dsymutil
+
+case "$ORIGINAL_DSYMUTIL_FOR_TARGET" in
+ ./dsymutil | ./dsymutil$build_exeext) ;;
+ *) ac_config_files="$ac_config_files dsymutil:exec-tool.in"
+ ;;
+esac
+
# Figure out what assembler alignment features are present.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler flags" >&5
$as_echo_n "checking assembler flags... " >&6; }
@@ -30303,6 +30413,52 @@ _ACEOF
fi
+if test x"$dsymutil_flag" = x"yes"; then
+
+ # If the user specified a dsymutil path, then we will already have the
+ # version string, otherwise, pick it up.
+ if test x"$gcc_cv_dsymutil" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dsymutil is a required tool for this system, but not found" >&5
+$as_echo "$as_me: WARNING: dsymutil is a required tool for this system, but not found" >&2;}
+ dsymutil_vers="tool unspecified"
+ elif test x"$dsymutil_vers" = x; then
+ dsymutil_vers=`$gcc_cv_dsymutil -v /dev/null 2>&1`
+ fi
+
+ dsymutil_temp=`echo $dsymutil_vers | sed 1q`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dsymutil version \"$dsymutil_temp\"" >&5
+$as_echo_n "checking dsymutil version \"$dsymutil_temp\"... " >&6; }
+ if echo $dsymutil_temp | grep dwarfutils- > /dev/null; then
+ dsymutil_kind=DWARFUTILS
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*dwarfutils-\([0-9\.]*\).*/\1/'`
+ elif echo $dsymutil_temp | grep clang- > /dev/null; then
+ dsymutil_kind=CLANG
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*clang-\([0-9\.]*\).*/\1/'`
+ elif echo $dsymutil_temp | grep 'LLVM version ' > /dev/null; then
+ dsymutil_kind=LLVM
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*LLVM\ version\ \([0-9\.]*\).*/\1/'`
+ else
+ dsymutil_kind=UNKNOWN
+ dsymutil_vers="0.0"
+ fi
+ dsymutil_major=`expr "$dsymutil_vers" : '\([0-9]*\)'`
+ dsymutil_minor=`expr "$dsymutil_vers" : '[0-9]*\.\([0-9]*\)'`
+ dsymutil_tiny=`expr "$dsymutil_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+ if test x"${dsymutil_minor}" = x; then
+ dsymutil_minor=0
+ fi
+ if test x"${dsymutil_tiny}" = x; then
+ dsymutil_tiny=0
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define DSYMUTIL_VERSION $dsymutil_kind,${dsymutil_major},${dsymutil_minor},${dsymutil_tiny}
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dsymutil_vers : $dsymutil_kind ${dsymutil_major} ${dsymutil_minor} ${dsymutil_tiny} " >&5
+$as_echo "$dsymutil_vers : $dsymutil_kind ${dsymutil_major} ${dsymutil_minor} ${dsymutil_tiny} " >&6; }
+fi
+
case $target_os in
win32 | pe | cygwin* | mingw32*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking broken PE linker dwarf5 support" >&5
@@ -33014,6 +33170,7 @@ do
"as") CONFIG_FILES="$CONFIG_FILES as:exec-tool.in" ;;
"collect-ld") CONFIG_FILES="$CONFIG_FILES collect-ld:exec-tool.in" ;;
"nm") CONFIG_FILES="$CONFIG_FILES nm:exec-tool.in" ;;
+ "dsymutil") CONFIG_FILES="$CONFIG_FILES dsymutil:exec-tool.in" ;;
"clearcap.map") CONFIG_LINKS="$CONFIG_LINKS clearcap.map:${srcdir}/config/$clearcap_map" ;;
"$all_outputs") CONFIG_FILES="$CONFIG_FILES $all_outputs" ;;
"default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
@@ -33648,6 +33805,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
"as":F) chmod +x as ;;
"collect-ld":F) chmod +x collect-ld ;;
"nm":F) chmod +x nm ;;
+ "dsymutil":F) chmod +x dsymutil ;;
"default":C)
case ${CONFIG_HEADERS} in
*auto-host.h:config.in*)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 7008939..26da073 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -316,8 +316,14 @@ gnu_ld_flag="$with_gnu_ld",
gnu_ld_flag=no)
case $target in
- *darwin*) ld64_flag=yes;; # Darwin can only use a ld64-compatible linker.
- *) ld64_flag=no;;
+ *darwin*)
+ ld64_flag=yes # Darwin can only use a ld64-compatible linker.
+ dsymutil_flag=yes # Darwin uses dsymutil to link debug.
+ ;;
+ *)
+ ld64_flag=no
+ dsymutil_flag=no
+ ;;
esac
# With pre-defined ld
@@ -353,6 +359,31 @@ AC_ARG_WITH(demangler-in-ld,
demangler_in_ld="$with_demangler_in_ld",
demangler_in_ld=yes)
+# Allow the user to specify a dsymutil executable (used on Darwin only, so far)
+AC_ARG_WITH(dsymutil,
+[AS_HELP_STRING([--with-dsymutil], [arrange to use the specified dsymutil (full pathname)])],
+DEFAULT_DSYMUTIL="$with_dsymutil")
+
+dsymutil_vers=
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+ if test ! -x "$DEFAULT_DSYMUTIL"; then
+ AC_MSG_ERROR([cannot execute: $DEFAULT_DSYMUTIL: check --with-dsymutil or env. var. DEFAULT_DSYMUTIL])
+ else
+ if dsymutil_vers=`$DEFAULT_DSYMUTIL -v /dev/null 2>&1`; then
+ dsymutil_flag=yes
+ fi
+ fi
+ AC_DEFINE_UNQUOTED(DEFAULT_DSYMUTIL,"$DEFAULT_DSYMUTIL",
+ [Define to enable the use of a default debug linker.])
+fi
+
+AC_MSG_CHECKING([whether a default dsymutil was specified])
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+ AC_MSG_RESULT([yes ($DEFAULT_DSYMUTIL)])
+else
+ AC_MSG_RESULT(no)
+fi
+
# ----------------------
# Find default assembler
# ----------------------
@@ -2852,6 +2883,27 @@ else
AC_MSG_RESULT($gcc_cv_otool)
fi
+# Figure out the dsymutil we will use.
+AS_VAR_SET_IF(gcc_cv_dsymutil,, [
+if test -x "$DEFAULT_DSYMUTIL"; then
+ gcc_cv_dsymutil="$DEFAULT_DSYMUTIL"
+elif test -x dsymutil$build_exeext; then
+ gcc_cv_dsymutil=./dsymutil$build_exeext
+elif ( set dummy $DSYMUTIL_FOR_TARGET; test -x $[2] ); then
+ gcc_cv_dsymutil=$DSYMUTIL_FOR_TARGET
+elif ( set dummy $DSYMUTIL; test -x $[2] ); then
+ gcc_cv_dsymutil=$DSYMUTIL
+else
+ AC_PATH_PROG(gcc_cv_dsymutil, $DSYMUTIL_FOR_TARGET)
+fi])
+
+ORIGINAL_DSYMUTIL_FOR_TARGET=$gcc_cv_dsymutil
+AC_SUBST(ORIGINAL_DSYMUTIL_FOR_TARGET)
+case "$ORIGINAL_DSYMUTIL_FOR_TARGET" in
+ ./dsymutil | ./dsymutil$build_exeext) ;;
+ *) AC_CONFIG_FILES(dsymutil:exec-tool.in, [chmod +x dsymutil]) ;;
+esac
+
# Figure out what assembler alignment features are present.
gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
[2,6,0],,
@@ -6240,6 +6292,46 @@ if test x"$ld64_flag" = x"yes"; then
[Define to 1 if ld64 supports '-export_dynamic'.])
fi
+if test x"$dsymutil_flag" = x"yes"; then
+
+ # If the user specified a dsymutil path, then we will already have the
+ # version string, otherwise, pick it up.
+ if test x"$gcc_cv_dsymutil" = x; then
+ AC_MSG_WARN([dsymutil is a required tool for this system, but not found])
+ dsymutil_vers="tool unspecified"
+ elif test x"$dsymutil_vers" = x; then
+ dsymutil_vers=`$gcc_cv_dsymutil -v /dev/null 2>&1`
+ fi
+
+ dsymutil_temp=`echo $dsymutil_vers | sed 1q`
+ AC_MSG_CHECKING(dsymutil version "$dsymutil_temp")
+ if echo $dsymutil_temp | grep dwarfutils- > /dev/null; then
+ dsymutil_kind=DWARFUTILS
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*dwarfutils-\([[0-9\.]]*\).*/\1/'`
+ elif echo $dsymutil_temp | grep clang- > /dev/null; then
+ dsymutil_kind=CLANG
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*clang-\([[0-9\.]]*\).*/\1/'`
+ elif echo $dsymutil_temp | grep 'LLVM version ' > /dev/null; then
+ dsymutil_kind=LLVM
+ dsymutil_vers=`echo $dsymutil_temp | sed 's/.*LLVM\ version\ \([[0-9\.]]*\).*/\1/'`
+ else
+ dsymutil_kind=UNKNOWN
+ dsymutil_vers="0.0"
+ fi
+ dsymutil_major=`expr "$dsymutil_vers" : '\([[0-9]]*\)'`
+ dsymutil_minor=`expr "$dsymutil_vers" : '[[0-9]]*\.\([[0-9]]*\)'`
+ dsymutil_tiny=`expr "$dsymutil_vers" : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test x"${dsymutil_minor}" = x; then
+ dsymutil_minor=0
+ fi
+ if test x"${dsymutil_tiny}" = x; then
+ dsymutil_tiny=0
+ fi
+ AC_DEFINE_UNQUOTED(DSYMUTIL_VERSION, [$dsymutil_kind,${dsymutil_major},${dsymutil_minor},${dsymutil_tiny}],
+ [Define to the dsymutil version.])
+ AC_MSG_RESULT($dsymutil_vers : $dsymutil_kind ${dsymutil_major} ${dsymutil_minor} ${dsymutil_tiny} )
+fi
+
case $target_os in
win32 | pe | cygwin* | mingw32*)
AC_MSG_CHECKING(broken PE linker dwarf5 support)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 01b29b1..39e5ec3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,173 @@
+2021-07-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/82110
+ * init.c (build_aggr_init): Return error_mark_node if
+ expand_aggr_init_1 returns false.
+ (expand_default_init): Change return type to bool. Return false
+ on error, true on success.
+ (expand_aggr_init_1): Likewise.
+
+2021-07-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/101098
+ * decl.c (function_requirements_equivalent_p): Only compare
+ trailing requirements on a specialization.
+
+2021-07-09 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (build_actor_fn): Move common code to
+ act_des_fn.
+ (build_destroy_fn): Likewise.
+ (act_des_fn): Build the void return here. Ensure that the
+ source location matches the original function.
+
+2021-07-09 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc
+ (coro_rewrite_function_body): Connect the replacement
+ function block to the block nest correctly.
+
+2021-07-09 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101181
+ * constraint.cc (tsubst_requires_expr): Pass complain/in_decl to
+ add_extra_args.
+ * cp-tree.h (add_extra_args): Add complain/in_decl parameters.
+ * pt.c (build_extra_args): Make a copy of args.
+ (add_extra_args): Add complain/in_decl parameters. Enable the
+ code for handling the case where the extra arguments are
+ dependent.
+ (tsubst_pack_expansion): Pass complain/in_decl to
+ add_extra_args.
+ (tsubst_template_args): Handle missing template arguments.
+ (tsubst_expr) <case IF_STMT>: Pass complain/in_decl to
+ add_extra_args.
+
+2021-07-09 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101247
+ * pt.c (any_template_parm_r) <case TEMPLATE_DECL>: Just walk the
+ DECL_CONTEXT.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/101372
+ * module.cc (identifier): Suppress warning.
+ (module_state::read_macro_maps): Remove warning suppression.
+ (module_state::install_macros): Ditto.
+
+2021-07-08 Marek Polacek <polacek@redhat.com>
+
+ PR c++/101087
+ * cp-tree.h (unevaluated_p): New.
+ * except.c (check_noexcept_r): Use it. Don't walk into
+ unevaluated operands.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/101374
+ * module.cc (module_state::read_macro_maps): Temporarily disable
+ -Warray-bounds.
+ (module_state::install_macros): Same.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * error.c (cp_printer): Remove support for %G and %K.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.h (struct cp_lexer): Add in_omp_attribute_pragma member.
+ (struct cp_omp_declare_simd_data): Likewise.
+ * cp-tree.h (enum cp_tree_index): Add CPTI_OMP_IDENTIFIER.
+ (omp_identifier): Define.
+ * parser.c (cp_parser_skip_to_pragma_eol): Handle
+ in_omp_attribute_pragma CPP_PRAGMA_EOL followed by CPP_EOF.
+ (cp_parser_require_pragma_eol): Likewise.
+ (struct cp_omp_attribute_data): New type.
+ (cp_parser_handle_statement_omp_attributes): New function.
+ (cp_parser_statement): Handle OpenMP directives in statement's
+ attribute-specifier-seq.
+ (cp_parser_omp_directive_args, cp_parser_omp_sequence_args): New
+ functions.
+ (cp_parser_std_attribute): Handle omp::directive and omp::sequence
+ attributes.
+ (cp_parser_omp_all_clauses): If in_omp_attribute_pragma, allow
+ a comma also before the first clause.
+ (cp_parser_omp_allocate): Likewise.
+ (cp_parser_omp_atomic): Likewise.
+ (cp_parser_omp_depobj): Likewise.
+ (cp_parser_omp_flush): Likewise.
+ (cp_parser_omp_ordered): Likewise.
+ (cp_parser_omp_declare_simd): Save in_omp_attribute_pragma
+ into struct cp_omp_declare_simd_data.
+ (cp_finish_omp_declare_variant): Add in_omp_attribute_pragma
+ argument. If set, allow a comma also before match clause.
+ (cp_parser_late_parsing_omp_declare_simd): If in_omp_attribute_pragma,
+ allow a comma also before the first clause. Adjust
+ cp_finish_omp_declare_variant caller.
+ (cp_parser_omp_declare_target): If in_omp_attribute_pragma, allow
+ a comma also before the first clause.
+ (cp_parser_omp_declare_reduction_exprs): Likewise.
+ (cp_parser_omp_requires): Likewise.
+ * decl.c (initialize_predefined_identifiers): Initialize
+ omp_identifier.
+ * decl2.c (cplus_decl_attributes): Reject omp::directive and
+ omp::sequence attributes.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/101297
+ * parser.c (cp_parser_omp_atomic): Consume comma only if it
+ appears before a CPP_NAME.
+
+2021-07-02 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101247
+ * pt.c (any_template_parm_r) <case TEMPLATE_DECL>: Rewrite to
+ use common_enclosing_class and to not depend on the TREE_TYPE
+ of outer levels pointing to the corresponding primary template.
+
+2021-07-01 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101194
+ * constexpr.c (cxx_eval_array_reference): When the element type
+ is an empty type and the corresponding element is omitted, just
+ return an empty CONSTRUCTOR instead of attempting value
+ initialization.
+
+2021-07-01 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/96204
+ * pt.c (finish_template_variable): Pass the partially
+ instantiated template and its args to instantiate_template.
+ (instantiate_class_template_1): No need to call
+ push_nested_class and pop_nested_class around the call to
+ most_specialized_partial_spec.
+ (instantiate_template_1): Pass the partially instantiated
+ template to lookup_template_variable.
+ (most_specialized_partial_spec): Use push_access_scope_guard
+ to set the access scope appropriately. Use
+ deferring_access_check_sentinel to force access to get checked
+ immediately.
+ (instantiate_decl): Just pass the VAR_DECL to
+ most_specialized_partial_spec.
+
+2021-06-30 Patrick Palka <ppalka@redhat.com>
+
+ * constraint.cc (get_normalized_constraints_from_decl): Use
+ push_access_scope_guard instead of push_nested_class_guard.
+ * cp-tree.h (struct push_nested_class_guard): Replace with ...
+ (struct push_access_scope_guard): ... this.
+ * pt.c (push_access_scope): When the argument corresponds to
+ a class type, push the class instead of its context.
+ (pop_access_scope): Adjust accordingly.
+
+2021-06-30 Marek Polacek <polacek@redhat.com>
+
+ PR c++/100975
+ DR 2397
+ * decl.c (create_array_type_for_decl): Allow array of auto.
+
2021-06-29 Jason Merrill <jason@redhat.com>
* pt.c (instantiate_decl): Only consider partial specializations of
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4cd9db3..39787f3 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3845,7 +3845,9 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */
tree val;
constexpr_ctx new_ctx;
- if (CP_AGGREGATE_TYPE_P (elem_type))
+ if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
+ return build_constructor (elem_type, NULL);
+ else if (CP_AGGREGATE_TYPE_P (elem_type))
{
tree empty_ctor = build_constructor (init_list_type_node, NULL);
val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 6df3ca6..4ee5215 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -926,12 +926,7 @@ get_normalized_constraints_from_decl (tree d, bool diag = false)
tree norm = NULL_TREE;
if (tree ci = get_constraints (decl))
{
- push_nested_class_guard pncs (DECL_CONTEXT (d));
-
- temp_override<tree> ovr (current_function_decl);
- if (TREE_CODE (decl) == FUNCTION_DECL)
- current_function_decl = decl;
-
+ push_access_scope_guard pas (decl);
norm = get_normalized_constraints_from_info (ci, tmpl, diag);
}
@@ -2271,7 +2266,8 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
/* A requires-expression is an unevaluated context. */
cp_unevaluated u;
- args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args);
+ args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
+ info.complain, info.in_decl);
if (processing_template_decl)
{
/* We're partially instantiating a generic lambda. Substituting into
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index a1b0b31..54ffdc8 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2155,13 +2155,6 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
/* One param, the coro frame pointer. */
tree actor_fp = DECL_ARGUMENTS (actor);
- /* A void return. */
- tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
- DECL_ARTIFICIAL (resdecl) = 1;
- DECL_IGNORED_P (resdecl) = 1;
- DECL_RESULT (actor) = resdecl;
- DECL_COROUTINE_P (actor) = 1;
-
/* We have a definition here. */
TREE_STATIC (actor) = 1;
@@ -2532,15 +2525,8 @@ build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
/* One param, the coro frame pointer. */
tree destr_fp = DECL_ARGUMENTS (destroy);
- /* A void return. */
- tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
- DECL_ARTIFICIAL (resdecl) = 1;
- DECL_IGNORED_P (resdecl) = 1;
- DECL_RESULT (destroy) = resdecl;
-
/* We have a definition here. */
TREE_STATIC (destroy) = 1;
- DECL_COROUTINE_P (destroy) = 1;
tree destr_outer = push_stmt_list ();
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
@@ -4000,15 +3986,19 @@ static tree
act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
{
tree fn_name = get_fn_local_identifier (orig, name);
+ location_t loc = DECL_SOURCE_LOCATION (orig);
tree fn = build_lang_decl (FUNCTION_DECL, fn_name, fn_type);
DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
+ DECL_SOURCE_LOCATION (fn) = loc;
DECL_ARTIFICIAL (fn) = true;
DECL_INITIAL (fn) = error_mark_node;
+
tree id = get_identifier ("frame_ptr");
tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
DECL_CONTEXT (fp) = fn;
DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
DECL_ARGUMENTS (fn) = fp;
+
/* Copy selected attributes from the original function. */
TREE_USED (fn) = TREE_USED (orig);
if (DECL_SECTION_NAME (orig))
@@ -4020,6 +4010,17 @@ act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig);
/* Apply attributes from the original fn. */
DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig));
+
+ /* A void return. */
+ tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
+ DECL_CONTEXT (resdecl) = fn;
+ DECL_ARTIFICIAL (resdecl) = 1;
+ DECL_IGNORED_P (resdecl) = 1;
+ DECL_RESULT (fn) = resdecl;
+
+ /* This is a coroutine component. */
+ DECL_COROUTINE_P (fn) = 1;
+
return fn;
}
@@ -4055,8 +4056,8 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig,
BIND_EXPR_BLOCK (first) = replace_blk;
/* The top block has one child, so far, and we have now got a
superblock. */
- BLOCK_SUPERCONTEXT (block) = top_block;
- BLOCK_SUBBLOCKS (top_block) = block;
+ BLOCK_SUPERCONTEXT (replace_blk) = top_block;
+ BLOCK_SUBBLOCKS (top_block) = replace_blk;
}
/* Wrap the function body in a try {} catch (...) {} block, if exceptions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6f71371..b1cf44e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -176,6 +176,7 @@ enum cp_tree_index
CPTI_HEAP_DELETED_IDENTIFIER,
CPTI_HEAP_VEC_UNINIT_IDENTIFIER,
CPTI_HEAP_VEC_IDENTIFIER,
+ CPTI_OMP_IDENTIFIER,
CPTI_LANG_NAME_C,
CPTI_LANG_NAME_CPLUSPLUS,
@@ -337,6 +338,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define heap_deleted_identifier cp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]
#define heap_vec_uninit_identifier cp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER]
#define heap_vec_identifier cp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]
+#define omp_identifier cp_global_trees[CPTI_OMP_IDENTIFIER]
#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C]
#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
@@ -7289,7 +7291,7 @@ extern void add_mergeable_specialization (bool is_decl, bool is_alias,
tree outer, unsigned);
extern tree add_to_template_args (tree, tree);
extern tree add_outermost_template_args (tree, tree);
-extern tree add_extra_args (tree, tree);
+extern tree add_extra_args (tree, tree, tsubst_flags_t, tree);
extern tree build_extra_args (tree, tree, tsubst_flags_t);
/* in rtti.c */
@@ -8463,21 +8465,37 @@ is_constrained_auto (const_tree t)
return is_auto (t) && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
}
-/* RAII class to push/pop class scope T; if T is not a class, do nothing. */
+/* True if CODE, a tree code, denotes a tree whose operand is not evaluated
+ as per [expr.context], i.e., an operand to sizeof, typeof, decltype, or
+ alignof. */
-struct push_nested_class_guard
+inline bool
+unevaluated_p (tree_code code)
+{
+ return (code == DECLTYPE_TYPE
+ || code == ALIGNOF_EXPR
+ || code == SIZEOF_EXPR
+ || code == NOEXCEPT_EXPR);
+}
+
+/* RAII class to push/pop the access scope for T. */
+
+struct push_access_scope_guard
{
- bool push;
- push_nested_class_guard (tree t)
- : push (t && CLASS_TYPE_P (t))
+ tree decl;
+ push_access_scope_guard (tree t)
+ : decl (t)
{
- if (push)
- push_nested_class (t);
+ if (VAR_OR_FUNCTION_DECL_P (decl)
+ || TREE_CODE (decl) == TYPE_DECL)
+ push_access_scope (decl);
+ else
+ decl = NULL_TREE;
}
- ~push_nested_class_guard ()
+ ~push_access_scope_guard ()
{
- if (push)
- pop_nested_class ();
+ if (decl)
+ pop_access_scope (decl);
}
};
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fa6af6f..0df689b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -955,7 +955,9 @@ static bool
function_requirements_equivalent_p (tree newfn, tree oldfn)
{
/* In the concepts TS, the combined constraints are compared. */
- if (cxx_dialect < cxx20)
+ if (cxx_dialect < cxx20
+ && (DECL_TEMPLATE_SPECIALIZATION (newfn)
+ <= DECL_TEMPLATE_SPECIALIZATION (oldfn)))
{
tree ci1 = get_constraints (oldfn);
tree ci2 = get_constraints (newfn);
@@ -4387,6 +4389,7 @@ initialize_predefined_identifiers (void)
{"heap deleted", &heap_deleted_identifier, cik_normal},
{"heap [] uninit", &heap_vec_uninit_identifier, cik_normal},
{"heap []", &heap_vec_identifier, cik_normal},
+ {"omp", &omp_identifier, cik_normal},
{NULL, NULL, cik_normal}
};
@@ -10969,17 +10972,6 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
if (type == error_mark_node || size == error_mark_node)
return error_mark_node;
- /* 8.3.4/1: If the type of the identifier of D contains the auto
- type-specifier, the program is ill-formed. */
- if (type_uses_auto (type))
- {
- if (name)
- error_at (loc, "%qD declared as array of %qT", name, type);
- else
- error ("creating array of %qT", type);
- return error_mark_node;
- }
-
/* If there are some types which cannot be array elements,
issue an error-message and return. */
switch (TREE_CODE (type))
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 090a83b..9564b0d 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1584,6 +1584,31 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
cp_check_const_attributes (attributes);
+ if ((flag_openmp || flag_openmp_simd) && attributes != error_mark_node)
+ {
+ bool diagnosed = false;
+ for (tree *pa = &attributes; *pa; )
+ {
+ if (get_attribute_namespace (*pa) == omp_identifier)
+ {
+ tree name = get_attribute_name (*pa);
+ if (is_attribute_p ("directive", name)
+ || is_attribute_p ("sequence", name))
+ {
+ if (!diagnosed)
+ {
+ error ("%<omp::%E%> not allowed to be specified in this "
+ "context", name);
+ diagnosed = true;
+ }
+ *pa = TREE_CHAIN (*pa);
+ continue;
+ }
+ }
+ pa = &TREE_CHAIN (*pa);
+ }
+ }
+
if (TREE_CODE (*decl) == TEMPLATE_DECL)
decl = &DECL_TEMPLATE_RESULT (*decl);
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 4a89b34..012a4ec 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4338,10 +4338,8 @@ defer_phase_2_of_type_diff (deferred_printed_type *deferred,
%D declaration.
%E expression.
%F function declaration.
- %G gcall *
%H type difference (from).
%I type difference (to).
- %K tree
%L language as used in extern "lang".
%O binary operator.
%P function parameter whose position is indicated by an integer.
@@ -4391,9 +4389,6 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
break;
case 'E': result = expr_to_string (next_tree); break;
case 'F': result = fndecl_to_string (next_tree, verbose); break;
- case 'G':
- percent_G_format (text);
- return true;
case 'H':
defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree,
buffer_ptr, verbose, *quoted);
@@ -4402,10 +4397,6 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree,
buffer_ptr, verbose, *quoted);
return true;
- case 'K':
- t = va_arg (*text->args_ptr, tree);
- percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t));
- return true;
case 'L': result = language_to_string (next_lang); break;
case 'O': result = op_to_string (false, next_tcode); break;
case 'P': result = parm_to_string (next_int); break;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index a8cea53..a8acbc4 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1033,12 +1033,15 @@ check_handlers (tree handlers)
expression whose type is a polymorphic class type (10.3). */
static tree
-check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
+check_noexcept_r (tree *tp, int *walk_subtrees, void *)
{
tree t = *tp;
enum tree_code code = TREE_CODE (t);
- if ((code == CALL_EXPR && CALL_EXPR_FN (t))
- || code == AGGR_INIT_EXPR)
+
+ if (unevaluated_p (code))
+ *walk_subtrees = false;
+ else if ((code == CALL_EXPR && CALL_EXPR_FN (t))
+ || code == AGGR_INIT_EXPR)
{
/* We can only use the exception specification of the called function
for determining the value of a noexcept expression; we can't use
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 88f6f90..d47e405 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see
static bool begin_init_stmts (tree *, tree *);
static tree finish_init_stmts (bool, tree, tree);
static void construct_virtual_base (tree, tree);
-static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
-static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
+static bool expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
+static bool expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
static void perform_member_init (tree, tree);
static int member_init_ok_or_else (tree, tree, tree);
static void expand_virtual_init (tree, tree);
@@ -1838,12 +1838,14 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
destroy_temps = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
- expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
- init, LOOKUP_NORMAL|flags, complain);
+ bool ok = expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
+ init, LOOKUP_NORMAL|flags, complain);
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile;
+ if (!ok)
+ return error_mark_node;
if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
&& TREE_SIDE_EFFECTS (stmt_expr)
@@ -1854,7 +1856,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
return stmt_expr;
}
-static void
+static bool
expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
tsubst_flags_t complain)
{
@@ -1889,6 +1891,9 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
happen for direct-initialization, too. */
init = digest_init (type, init, complain);
+ if (init == error_mark_node)
+ return false;
+
/* A CONSTRUCTOR of the target's type is a previously digested
initializer, whether that happened just above or in
cp_parser_late_parsing_nsdmi.
@@ -1910,7 +1915,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
finish_expr_stmt (init);
- return;
+ return true;
}
if (init && TREE_CODE (init) != TREE_LIST
@@ -1927,8 +1932,12 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
have already built up the constructor call so we could wrap it
in an exception region. */;
else
- init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
- flags, complain | tf_no_cleanup);
+ {
+ init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
+ flags, complain | tf_no_cleanup);
+ if (init == error_mark_node)
+ return false;
+ }
if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
/* We need to protect the initialization of a catch parm with a
@@ -1944,7 +1953,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
finish_expr_stmt (init);
- return;
+ return true;
}
if (init == NULL_TREE)
@@ -1982,6 +1991,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
&parms, binfo, flags,
complain);
base = fold_build_cleanup_point_expr (void_type_node, base);
+ if (complete == error_mark_node || base == error_mark_node)
+ return false;
rval = build_if_in_charge (complete, base);
}
else
@@ -1991,6 +2002,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
complain);
+ if (rval == error_mark_node)
+ return false;
}
if (parms != NULL)
@@ -2010,10 +2023,12 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* FIXME put back convert_to_void? */
if (TREE_SIDE_EFFECTS (rval))
finish_expr_stmt (rval);
+
+ return true;
}
/* This function is responsible for initializing EXP with INIT
- (if any).
+ (if any). Returns true on success, false on failure.
BINFO is the binfo of the type for who we are performing the
initialization. For example, if W is a virtual base class of A and B,
@@ -2032,7 +2047,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
FLAGS is just passed to `build_new_method_call'. See that function
for its description. */
-static void
+static bool
expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
tsubst_flags_t complain)
{
@@ -2058,7 +2073,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
if (init)
finish_expr_stmt (init);
gcc_assert (!cleanups);
- return;
+ return true;
}
/* List-initialization from {} becomes value-initialization for non-aggregate
@@ -2096,7 +2111,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* If we don't need to mess with the constructor at all,
then we're done. */
if (! type_build_ctor_call (type))
- return;
+ return true;
/* Otherwise fall through and call the constructor. */
init = NULL_TREE;
@@ -2104,7 +2119,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* We know that expand_default_init can handle everything we want
at this point. */
- expand_default_init (binfo, true_exp, exp, init, flags, complain);
+ return expand_default_init (binfo, true_exp, exp, init, flags, complain);
}
/* Report an error if TYPE is not a user-defined, class type. If
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f259515..ccbde29 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -274,7 +274,14 @@ static inline cpp_hashnode *cpp_node (tree id)
static inline tree identifier (const cpp_hashnode *node)
{
+ /* HT_NODE() expands to node->ident that HT_IDENT_TO_GCC_IDENT()
+ then subtracts a nonzero constant, deriving a pointer to
+ a different member than ident. That's strictly undefined
+ and detected by -Warray-bounds. Suppress it. See PR 101372. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
return HT_IDENT_TO_GCC_IDENT (HT_NODE (const_cast<cpp_hashnode *> (node)));
+#pragma GCC diagnostic pop
}
/* Id for dumping module information. */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 02daa7a..93698aa 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1,4 +1,3 @@
-
/* -*- C++ -*- Parser.
Copyright (C) 2000-2021 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
@@ -4061,6 +4060,14 @@ cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok)
/* Ensure that the pragma is not parsed again. */
cp_lexer_purge_tokens_after (parser->lexer, pragma_tok);
parser->lexer->in_pragma = false;
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ {
+ parser->lexer = parser->lexer->next;
+ /* Put the current source position back where it was before this
+ lexer was pushed. */
+ cp_lexer_set_source_position_from_token (parser->lexer->next_token);
+ }
}
}
@@ -4073,6 +4080,14 @@ cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
parser->lexer->in_pragma = false;
if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ else if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ {
+ parser->lexer = parser->lexer->next;
+ /* Put the current source position back where it was before this
+ lexer was pushed. */
+ cp_lexer_set_source_position_from_token (parser->lexer->next_token);
+ }
}
/* This is a simple wrapper around make_typename_type. When the id is
@@ -11631,6 +11646,187 @@ add_debug_begin_stmt (location_t loc)
add_stmt (stmt);
}
+struct cp_omp_attribute_data
+{
+ cp_token_cache *tokens;
+ const c_omp_directive *dir;
+ c_omp_directive_kind kind;
+};
+
+/* Handle omp::directive and omp::sequence attributes in ATTRS
+ (if any) at the start of a statement. */
+
+static tree
+cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
+{
+ if (!flag_openmp && !flag_openmp_simd)
+ return attrs;
+
+ auto_vec<cp_omp_attribute_data, 16> vec;
+ int cnt = 0;
+ int tokens = 0;
+ for (tree *pa = &attrs; *pa; )
+ if (get_attribute_namespace (*pa) == omp_identifier
+ && is_attribute_p ("directive", get_attribute_name (*pa)))
+ {
+ cnt++;
+ for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
+ {
+ tree d = TREE_VALUE (a);
+ gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
+ cp_token *first = DEFPARSE_TOKENS (d)->first;
+ cp_token *last = DEFPARSE_TOKENS (d)->last;
+ const char *directive[3] = {};
+ for (int i = 0; i < 3; i++)
+ {
+ tree id = NULL_TREE;
+ if (first + i == last)
+ break;
+ if (first[i].type == CPP_NAME)
+ id = first[i].u.value;
+ else if (first[i].type == CPP_KEYWORD)
+ id = ridpointers[(int) first[i].keyword];
+ else
+ break;
+ directive[i] = IDENTIFIER_POINTER (id);
+ }
+ const c_omp_directive *dir = NULL;
+ if (directive[0])
+ dir = c_omp_categorize_directive (directive[0], directive[1],
+ directive[2]);
+ if (dir == NULL)
+ {
+ error_at (first->location,
+ "unknown OpenMP directive name in %<omp::directive%>"
+ " attribute argument");
+ continue;
+ }
+ c_omp_directive_kind kind = dir->kind;
+ if (dir->id == PRAGMA_OMP_ORDERED)
+ {
+ /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
+ depend clause. */
+ if (directive[1] && strcmp (directive[1], "depend") == 0)
+ kind = C_OMP_DIR_STANDALONE;
+ else if (first + 2 < last
+ && first[1].type == CPP_COMMA
+ && first[2].type == CPP_NAME
+ && strcmp (IDENTIFIER_POINTER (first[2].u.value),
+ "depend") == 0)
+ kind = C_OMP_DIR_STANDALONE;
+ }
+ /* else if (dir->id == PRAGMA_OMP_ERROR)
+ {
+ error with at(execution) clause is C_OMP_DIR_STANDALONE.
+ } */
+ cp_omp_attribute_data v = { DEFPARSE_TOKENS (d), dir, kind };
+ vec.safe_push (v);
+ if (flag_openmp || dir->simd)
+ tokens += (last - first) + 1;
+ }
+ cp_omp_attribute_data v = {};
+ vec.safe_push (v);
+ *pa = TREE_CHAIN (*pa);
+ }
+ else
+ pa = &TREE_CHAIN (*pa);
+
+ unsigned int i;
+ cp_omp_attribute_data *v;
+ cp_omp_attribute_data *construct_seen = nullptr;
+ cp_omp_attribute_data *standalone_seen = nullptr;
+ cp_omp_attribute_data *prev_standalone_seen = nullptr;
+ FOR_EACH_VEC_ELT (vec, i, v)
+ if (v->tokens)
+ {
+ if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
+ construct_seen = v;
+ else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
+ standalone_seen = v;
+ }
+ else
+ {
+ if (standalone_seen && !prev_standalone_seen)
+ {
+ prev_standalone_seen = standalone_seen;
+ standalone_seen = nullptr;
+ }
+ }
+
+ if (cnt > 1 && construct_seen)
+ {
+ error_at (construct_seen->tokens->first->location,
+ "OpenMP construct among %<omp::directive%> attributes"
+ " requires all %<omp::directive%> attributes on the"
+ " same statement to be in the same %<omp::sequence%>");
+ return attrs;
+ }
+ if (cnt > 1 && standalone_seen && prev_standalone_seen)
+ {
+ error_at (standalone_seen->tokens->first->location,
+ "multiple OpenMP standalone directives among"
+ " %<omp::directive%> attributes must be all within the"
+ " same %<omp::sequence%>");
+ return attrs;
+ }
+
+ if (prev_standalone_seen)
+ standalone_seen = prev_standalone_seen;
+ if (standalone_seen
+ && !cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ error_at (standalone_seen->tokens->first->location,
+ "standalone OpenMP directives in %<omp::directive%> attribute"
+ " can only appear on an empty statement");
+ return attrs;
+ }
+
+ if (!tokens)
+ return attrs;
+ tokens++;
+ cp_lexer *lexer = cp_lexer_alloc ();
+ lexer->debugging_p = parser->lexer->debugging_p;
+ vec_safe_reserve (lexer->buffer, tokens, true);
+ FOR_EACH_VEC_ELT (vec, i, v)
+ {
+ if (!v->tokens)
+ continue;
+ if (!flag_openmp && !v->dir->simd)
+ continue;
+ cp_token *first = v->tokens->first;
+ cp_token *last = v->tokens->last;
+ cp_token tok = {};
+ tok.type = CPP_PRAGMA;
+ tok.keyword = RID_MAX;
+ tok.u.value = build_int_cst (NULL, v->dir->id);
+ tok.location = first->location;
+ lexer->buffer->quick_push (tok);
+ while (++first < last)
+ lexer->buffer->quick_push (*first);
+ tok = {};
+ tok.type = CPP_PRAGMA_EOL;
+ tok.keyword = RID_MAX;
+ tok.location = last->location;
+ lexer->buffer->quick_push (tok);
+ }
+ cp_token tok = {};
+ tok.type = CPP_EOF;
+ tok.keyword = RID_MAX;
+ tok.location = lexer->buffer->last ().location;
+ lexer->buffer->quick_push (tok);
+ lexer->next = parser->lexer;
+ lexer->next_token = lexer->buffer->address ();
+ lexer->last_token = lexer->next_token
+ + lexer->buffer->length ()
+ - 1;
+ lexer->in_omp_attribute_pragma = true;
+ parser->lexer = lexer;
+ /* Move the current source position to that of the first token in the
+ new lexer. */
+ cp_lexer_set_source_position_from_token (lexer->next_token);
+ return attrs;
+}
+
/* Parse a statement.
statement:
@@ -11681,8 +11877,10 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
tree statement, std_attrs = NULL_TREE;
cp_token *token;
location_t statement_location, attrs_loc;
+ bool in_omp_attribute_pragma;
restart:
+ in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
if (if_p != NULL)
*if_p = false;
/* There is no statement yet. */
@@ -11704,6 +11902,9 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
std_attrs = NULL_TREE;
}
+ if (std_attrs && (flag_openmp || flag_openmp_simd))
+ std_attrs = cp_parser_handle_statement_omp_attributes (parser, std_attrs);
+
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* Remember the location of the first token in the statement. */
@@ -11821,6 +12022,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
a statement all its own. */
else if (token->type == CPP_PRAGMA)
{
+ cp_lexer *lexer = parser->lexer;
+ bool do_restart = false;
/* Only certain OpenMP pragmas are attached to statements, and thus
are considered statements themselves. All others are not. In
the context of a compound, accept the pragma as a "statement" and
@@ -11829,6 +12032,13 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
if (in_compound)
cp_parser_pragma (parser, pragma_compound, if_p);
else if (!cp_parser_pragma (parser, pragma_stmt, if_p))
+ do_restart = true;
+ if (lexer->in_omp_attribute_pragma && !in_omp_attribute_pragma)
+ {
+ gcc_assert (parser->lexer != lexer);
+ cp_lexer_destroy (lexer);
+ }
+ if (do_restart)
goto restart;
return;
}
@@ -27935,6 +28145,92 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
return nreverse (attribute_list);
}
+/* Parse arguments of omp::directive attribute.
+
+ ( directive-name ,[opt] clause-list[opt] )
+
+ For directive just remember the first/last tokens for subsequent
+ parsing. */
+
+static void
+cp_parser_omp_directive_args (cp_parser *parser, tree attribute)
+{
+ cp_token *first = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (first->type == CPP_CLOSE_PAREN)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ error_at (first->location, "expected OpenMP directive name");
+ cp_lexer_consume_token (parser->lexer);
+ TREE_VALUE (attribute) = NULL_TREE;
+ return;
+ }
+ for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 2; n; --n)
+ cp_lexer_consume_token (parser->lexer);
+ cp_token *last = cp_lexer_peek_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ tree arg = make_node (DEFERRED_PARSE);
+ DEFPARSE_TOKENS (arg) = cp_token_cache_new (first, last);
+ DEFPARSE_INSTANTIATIONS (arg) = nullptr;
+ TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
+}
+
+/* Parse arguments of omp::sequence attribute.
+
+ ( omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... ) */
+
+static void
+cp_parser_omp_sequence_args (cp_parser *parser, tree attribute)
+{
+ matching_parens parens;
+ parens.consume_open (parser);
+ do
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME
+ && token->u.value == omp_identifier
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+ bool directive = false;
+ const char *p;
+ if (token->type != CPP_NAME)
+ p = "";
+ else
+ p = IDENTIFIER_POINTER (token->u.value);
+ if (strcmp (p, "directive") == 0)
+ directive = true;
+ else if (strcmp (p, "sequence") != 0)
+ {
+ error_at (token->location, "expected %<directive%> or %<sequence%>");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/false);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ cp_parser_required_error (parser, RT_OPEN_PAREN, false,
+ UNKNOWN_LOCATION);
+ else if (directive)
+ cp_parser_omp_directive_args (parser, attribute);
+ else
+ cp_parser_omp_sequence_args (parser, attribute);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ while (1);
+ if (!parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+}
+
/* Parse a standard C++11 attribute.
The returned representation is a TREE_LIST which TREE_PURPOSE is
@@ -28066,7 +28362,18 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
/* Now parse the optional argument clause of the attribute. */
if (token->type != CPP_OPEN_PAREN)
- return attribute;
+ {
+ if ((flag_openmp || flag_openmp_simd)
+ && attr_ns == omp_identifier
+ && (is_attribute_p ("directive", attr_id)
+ || is_attribute_p ("sequence", attr_id)))
+ {
+ error_at (token->location, "%<omp::%E%> attribute requires argument",
+ attr_id);
+ return NULL_TREE;
+ }
+ return attribute;
+ }
{
vec<tree, va_gc> *vec;
@@ -28093,6 +28400,23 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
if (as == NULL)
{
+ if ((flag_openmp || flag_openmp_simd) && attr_ns == omp_identifier)
+ {
+ if (is_attribute_p ("directive", attr_id))
+ {
+ cp_parser_omp_directive_args (parser, attribute);
+ return attribute;
+ }
+ else if (is_attribute_p ("sequence", attr_id))
+ {
+ TREE_VALUE (TREE_PURPOSE (attribute))
+ = get_identifier ("directive");
+ cp_parser_omp_sequence_args (parser, attribute);
+ TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
+ return attribute;
+ }
+ }
+
/* For unknown attributes, just skip balanced tokens instead of
trying to parse the arguments. */
for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
@@ -38675,7 +38999,12 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
if (nested && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
break;
- if (!first)
+ if (!first
+ /* OpenMP 5.1 allows optional comma in between directive-name and
+ clauses everywhere, but as we aren't done with OpenMP 5.0
+ implementation yet, let's allow it for now only in C++11
+ attributes. */
+ || (parser->lexer->in_omp_attribute_pragma && nested != 2))
{
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
@@ -39080,6 +39409,12 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
location_t loc = pragma_tok->location;
tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
matching_parens parens;
@@ -39171,7 +39506,10 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if ((!first || parser->lexer->in_omp_attribute_pragma)
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
first = false;
@@ -39733,6 +40071,10 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
tree clause = NULL_TREE;
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -39813,6 +40155,11 @@ static void
cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
{
enum memmodel mo = MEMMODEL_LAST;
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -41173,10 +41520,16 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
enum pragma_context context, bool *if_p)
{
location_t loc = pragma_tok->location;
+ int n = 1;
- if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ n = 2;
+
+ if (cp_lexer_nth_token_is (parser->lexer, n, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ tree id = cp_lexer_peek_nth_token (parser->lexer, n)->u.value;
const char *p = IDENTIFIER_POINTER (id);
if (strcmp (p, "depend") == 0)
@@ -43018,6 +43371,7 @@ cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
data.error_seen = false;
data.fndecl_seen = false;
data.variant_p = variant_p;
+ data.in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
data.tokens = vNULL;
data.clauses = NULL_TREE;
/* It is safe to take the address of a local variable; it will only be
@@ -43456,7 +43810,7 @@ cp_parser_omp_context_selector_specification (cp_parser *parser,
static tree
cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
- tree attrs)
+ tree attrs, bool in_omp_attribute_pragma)
{
matching_parens parens;
if (!parens.require_open (parser))
@@ -43514,6 +43868,12 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
location_t finish_loc = get_finish (varid.get_location ());
location_t varid_loc = make_location (caret_loc, start_loc, finish_loc);
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+
const char *clause = "";
location_t match_loc = cp_lexer_peek_token (parser->lexer)->location;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -43586,6 +43946,12 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
cp_lexer_consume_token (parser->lexer);
if (strcmp (kind, "simd") == 0)
{
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (data->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+
cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
"#pragma omp declare simd",
pragma_tok);
@@ -43600,7 +43966,9 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
else
{
gcc_assert (strcmp (kind, "variant") == 0);
- attrs = cp_finish_omp_declare_variant (parser, pragma_tok, attrs);
+ attrs
+ = cp_finish_omp_declare_variant (parser, pragma_tok, attrs,
+ data->in_omp_attribute_pragma);
}
cp_parser_pop_lexer (parser);
}
@@ -43631,7 +43999,11 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
tree clauses = NULL_TREE;
int device_type = 0;
bool only_device_type = true;
- if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ || (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)))
clauses
= cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
"#pragma omp declare target", pragma_tok);
@@ -43810,6 +44182,12 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
return false;
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if (parser->lexer->in_omp_attribute_pragma
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+
const char *p = "";
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
@@ -44244,7 +44622,10 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
location_t loc = pragma_tok->location;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if ((!first || parser->lexer->in_omp_attribute_pragma)
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
first = false;
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index a468b69..5ef7047 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -113,6 +113,10 @@ struct GTY (()) cp_lexer {
/* True if we're in the context of parsing a pragma, and should not
increment past the end-of-line marker. */
bool in_pragma;
+
+ /* True if we're in the context of OpenMP directives written as C++11
+ attributes turned into pragma. */
+ bool in_omp_attribute_pragma;
};
@@ -208,6 +212,8 @@ struct cp_omp_declare_simd_data {
bool error_seen; /* Set if error has been reported. */
bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
bool variant_p; /* Set for #pragma omp declare variant. */
+ bool in_omp_attribute_pragma; /* True if declare simd/variant comes from
+ C++11 attribute rather than pragma. */
vec<cp_token_cache_ptr> tokens;
tree clauses;
};
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d2936c1..cf0ce77 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -224,7 +224,7 @@ static void instantiate_body (tree pattern, tree args, tree d, bool nested);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
template, VAR_DECL for static member variable, or TYPE_DECL for
- alias template (needed by instantiate_decl). */
+ for a class or alias template (needed by instantiate_decl). */
void
push_access_scope (tree t)
@@ -234,6 +234,9 @@ push_access_scope (tree t)
if (DECL_FRIEND_CONTEXT (t))
push_nested_class (DECL_FRIEND_CONTEXT (t));
+ else if (DECL_IMPLICIT_TYPEDEF_P (t)
+ && CLASS_TYPE_P (TREE_TYPE (t)))
+ push_nested_class (TREE_TYPE (t));
else if (DECL_CLASS_SCOPE_P (t))
push_nested_class (DECL_CONTEXT (t));
else if (deduction_guide_p (t) && DECL_ARTIFICIAL (t))
@@ -260,6 +263,8 @@ pop_access_scope (tree t)
current_function_decl = saved_access_scope->pop();
if (DECL_FRIEND_CONTEXT (t)
+ || (DECL_IMPLICIT_TYPEDEF_P (t)
+ && CLASS_TYPE_P (TREE_TYPE (t)))
|| DECL_CLASS_SCOPE_P (t)
|| (deduction_guide_p (t) && DECL_ARTIFICIAL (t)))
pop_nested_class ();
@@ -10263,10 +10268,6 @@ finish_template_variable (tree var, tsubst_flags_t complain)
tree templ = TREE_OPERAND (var, 0);
tree arglist = TREE_OPERAND (var, 1);
- tree tmpl_args = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (templ));
- arglist = add_outermost_template_args (tmpl_args, arglist);
-
- templ = most_general_template (templ);
tree parms = DECL_TEMPLATE_PARMS (templ);
arglist = coerce_innermost_template_parms (parms, arglist, templ, complain,
/*req_all*/true,
@@ -10727,28 +10728,11 @@ any_template_parm_r (tree t, void *data)
break;
case TEMPLATE_DECL:
- {
- /* If T is a member template that shares template parameters with
- ctx_parms, we need to mark all those parameters for mapping. */
- tree dparms = DECL_TEMPLATE_PARMS (t);
- tree cparms = ftpi->ctx_parms;
- while (TMPL_PARMS_DEPTH (dparms) > ftpi->max_depth)
- dparms = TREE_CHAIN (dparms);
- while (TMPL_PARMS_DEPTH (cparms) > TMPL_PARMS_DEPTH (dparms))
- cparms = TREE_CHAIN (cparms);
- while (dparms
- && (TREE_TYPE (TREE_VALUE (dparms))
- != TREE_TYPE (TREE_VALUE (cparms))))
- dparms = TREE_CHAIN (dparms),
- cparms = TREE_CHAIN (cparms);
- if (dparms)
- {
- int ddepth = TMPL_PARMS_DEPTH (dparms);
- tree dargs = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (t)));
- for (int i = 0; i < ddepth; ++i)
- WALK_SUBTREE (TMPL_ARGS_LEVEL (dargs, i+1));
- }
- }
+ /* If T is a member template that shares template parameters with
+ ctx_parms, we need to mark all those parameters for mapping.
+ To that end, it should suffice to just walk the DECL_CONTEXT of
+ the template (assuming the template is not overly general). */
+ WALK_SUBTREE (DECL_CONTEXT (t));
break;
case LAMBDA_EXPR:
@@ -11769,11 +11753,8 @@ instantiate_class_template_1 (tree type)
deferring_access_check_sentinel acs (dk_no_deferred);
/* Determine what specialization of the original template to
- instantiate; do this relative to the scope of the class for
- sake of access checking. */
- push_nested_class (type);
+ instantiate. */
t = most_specialized_partial_spec (type, tf_warning_or_error);
- pop_nested_class ();
if (t == error_mark_node)
return error_mark_node;
else if (t)
@@ -12926,7 +12907,9 @@ extract_local_specs (tree pattern, tsubst_flags_t complain)
tree
build_extra_args (tree pattern, tree args, tsubst_flags_t complain)
{
- tree extra = args;
+ /* Make a copy of the extra arguments so that they won't get changed
+ out from under us. */
+ tree extra = copy_template_args (args);
if (local_specializations)
if (tree locals = extract_local_specs (pattern, complain))
extra = tree_cons (NULL_TREE, extra, locals);
@@ -12937,7 +12920,7 @@ build_extra_args (tree pattern, tree args, tsubst_flags_t complain)
normal template args to ARGS. */
tree
-add_extra_args (tree extra, tree args)
+add_extra_args (tree extra, tree args, tsubst_flags_t complain, tree in_decl)
{
if (extra && TREE_CODE (extra) == TREE_LIST)
{
@@ -12957,20 +12940,14 @@ add_extra_args (tree extra, tree args)
gcc_assert (!TREE_PURPOSE (extra));
extra = TREE_VALUE (extra);
}
-#if 1
- /* I think we should always be able to substitute dependent args into the
- pattern. If that turns out to be incorrect in some cases, enable the
- alternate code (and add complain/in_decl parms to this function). */
- gcc_checking_assert (!uses_template_parms (extra));
-#else
- if (!uses_template_parms (extra))
+ if (uses_template_parms (extra))
{
- gcc_unreachable ();
+ /* This can happen after dependent substitution into a
+ requires-expr or a lambda that uses constexpr if. */
extra = tsubst_template_args (extra, args, complain, in_decl);
args = add_outermost_template_args (args, extra);
}
else
-#endif
args = add_to_template_args (extra, args);
return args;
}
@@ -12996,7 +12973,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
pattern = PACK_EXPANSION_PATTERN (t);
/* Add in any args remembered from an earlier partial instantiation. */
- args = add_extra_args (PACK_EXPANSION_EXTRA_ARGS (t), args);
+ args = add_extra_args (PACK_EXPANSION_EXTRA_ARGS (t), args, complain, in_decl);
levels = TMPL_ARGS_DEPTH (args);
@@ -13368,7 +13345,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree orig_arg = TREE_VEC_ELT (t, i);
tree new_arg;
- if (TREE_CODE (orig_arg) == TREE_VEC)
+ if (!orig_arg)
+ new_arg = NULL_TREE;
+ else if (TREE_CODE (orig_arg) == TREE_VEC)
new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
else if (PACK_EXPANSION_P (orig_arg))
{
@@ -13418,8 +13397,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
for (i = 0, out = 0; i < len; i++)
{
- if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
- || ARGUMENT_PACK_P (TREE_VEC_ELT (orig_t, i)))
+ tree orig_arg = TREE_VEC_ELT (orig_t, i);
+ if (orig_arg
+ && (PACK_EXPANSION_P (orig_arg) || ARGUMENT_PACK_P (orig_arg))
&& TREE_CODE (elts[i]) == TREE_VEC)
{
int idx;
@@ -18447,7 +18427,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t);
IF_STMT_CONSTEVAL_P (stmt) = IF_STMT_CONSTEVAL_P (t);
if (IF_STMT_CONSTEXPR_P (t))
- args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args);
+ args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args, complain, in_decl);
tmp = RECUR (IF_COND (t));
tmp = finish_if_stmt_cond (tmp, stmt);
if (IF_STMT_CONSTEXPR_P (t)
@@ -21129,7 +21109,7 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
/* We need to determine if we're using a partial or explicit
specialization now, because the type of the variable could be
different. */
- tree tid = lookup_template_variable (gen_tmpl, targ_ptr);
+ tree tid = lookup_template_variable (tmpl, targ_ptr);
tree elt = most_specialized_partial_spec (tid, complain);
if (elt == error_mark_node)
pattern = error_mark_node;
@@ -24982,26 +24962,33 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
tree outer_args = NULL_TREE;
tree tmpl, args;
+ tree decl;
if (TYPE_P (target))
{
tree tinfo = CLASSTYPE_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
+ decl = TYPE_NAME (target);
}
else if (TREE_CODE (target) == TEMPLATE_ID_EXPR)
{
tmpl = TREE_OPERAND (target, 0);
args = TREE_OPERAND (target, 1);
+ decl = DECL_TEMPLATE_RESULT (tmpl);
}
else if (VAR_P (target))
{
tree tinfo = DECL_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
+ decl = target;
}
else
gcc_unreachable ();
+ push_access_scope_guard pas (decl);
+ deferring_access_check_sentinel acs (dk_no_deferred);
+
tree main_tmpl = most_general_template (tmpl);
/* For determining which partial specialization to use, only the
@@ -26006,8 +25993,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
if (variable_template_specialization_p (d))
{
/* Look up an explicit specialization, if any. */
- tree tid = lookup_template_variable (gen_tmpl, gen_args);
- tree elt = most_specialized_partial_spec (tid, tf_warning_or_error);
+ tree elt = most_specialized_partial_spec (d, tf_warning_or_error);
if (elt && elt != error_mark_node)
{
td = TREE_VALUE (elt);
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index eb17034..f0489c2 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,15 @@
+2021-07-03 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/101273
+ * toir.cc (IRVisitor::visit (ReturnStatement *)): Detect returns that
+ use a temporary, and replace with return value.
+
+2021-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/101282
+ * d-codegen.cc (build_assign): Force target_expr on RHS for non-POD
+ assignment expressions.
+
2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/100999
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 9a94473..ce7c17b 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1344,6 +1344,13 @@ build_assign (tree_code code, tree lhs, tree rhs)
d_mark_addressable (lhs);
CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
}
+ /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
+ else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
+ && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
+ {
+ /* LHS may be referenced by the RHS expression, so force a temporary. */
+ rhs = force_target_expr (rhs);
+ }
/* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
if (TREE_CODE (rhs) == TARGET_EXPR)
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index 41d07a7..eaee6f7 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -1034,14 +1034,37 @@ public:
/* Detect a call to a constructor function, or if returning a struct
literal, write result directly into the return value. */
StructLiteralExp *sle = NULL;
+ bool using_rvo_p = false;
if (DotVarExp *dve = (s->exp->op == TOKcall
&& s->exp->isCallExp ()->e1->op == TOKdotvar
? s->exp->isCallExp ()->e1->isDotVarExp ()
: NULL))
{
- sle = (dve->var->isCtorDeclaration ()
- ? dve->e1->isStructLiteralExp () : NULL);
+ if (dve->var->isCtorDeclaration ())
+ {
+ if (CommaExp *ce = dve->e1->isCommaExp ())
+ {
+ /* Temporary initialized inside a return expression, and
+ used as the return value. Replace it with the hidden
+ reference to allow RVO return. */
+ DeclarationExp *de = ce->e1->isDeclarationExp ();
+ VarExp *ve = ce->e2->isVarExp ();
+ if (de != NULL && ve != NULL
+ && ve->var == de->declaration
+ && ve->var->storage_class & STCtemp)
+ {
+ tree var = get_symbol_decl (ve->var);
+ TREE_ADDRESSABLE (var) = 1;
+ SET_DECL_VALUE_EXPR (var, decl);
+ DECL_HAS_VALUE_EXPR_P (var) = 1;
+ SET_DECL_LANG_NRVO (var, this->func_->shidden);
+ using_rvo_p = true;
+ }
+ }
+ else
+ sle = dve->e1->isStructLiteralExp ();
+ }
}
else
sle = s->exp->isStructLiteralExp ();
@@ -1050,11 +1073,16 @@ public:
{
StructDeclaration *sd = type->baseElemOf ()->isTypeStruct ()->sym;
sle->sym = build_address (this->func_->shidden);
+ using_rvo_p = true;
/* Fill any alignment holes in the return slot using memset. */
if (!identity_compare_p (sd) || sd->isUnionDeclaration ())
add_stmt (build_memset_call (this->func_->shidden));
+ }
+ if (using_rvo_p == true)
+ {
+ /* Generate: (expr, return <retval>); */
add_stmt (build_expr_dtor (s->exp));
}
else
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 93e7b4f..2345899 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -183,6 +183,7 @@ DEBUG_COUNTER (lim)
DEBUG_COUNTER (local_alloc_for_sched)
DEBUG_COUNTER (match)
DEBUG_COUNTER (merged_ipa_icf)
+DEBUG_COUNTER (phiopt_edge_range)
DEBUG_COUNTER (postreload_cse)
DEBUG_COUNTER (pre)
DEBUG_COUNTER (pre_insn)
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index d58586f..8361f68 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -991,51 +991,88 @@ print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
pp_set_prefix (pp, saved_prefix);
}
-/* Update the diag_class of DIAGNOSTIC based on its location
- relative to any
+/* Update the inlining info in CONTEXT for a DIAGNOSTIC. */
+
+static void
+get_any_inlining_info (diagnostic_context *context,
+ diagnostic_info *diagnostic)
+{
+ auto &ilocs = diagnostic->m_iinfo.m_ilocs;
+
+ if (context->set_locations_cb)
+ /* Retrieve the locations into which the expression about to be
+ diagnosed has been inlined, including those of all the callers
+ all the way down the inlining stack. */
+ context->set_locations_cb (context, diagnostic);
+ else
+ {
+ /* When there's no callback use just the one location provided
+ by the caller of the diagnostic function. */
+ location_t loc = diagnostic_location (diagnostic);
+ ilocs.safe_push (loc);
+ diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc);
+ }
+}
+
+/* Update the kind of DIAGNOSTIC based on its location(s), including
+ any of those in its inlining stack, relative to any
#pragma GCC diagnostic
directives recorded within CONTEXT.
- Return the new diag_class of DIAGNOSTIC if it was updated, or
- DK_UNSPECIFIED otherwise. */
+ Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
+ otherwise. */
static diagnostic_t
update_effective_level_from_pragmas (diagnostic_context *context,
diagnostic_info *diagnostic)
{
- diagnostic_t diag_class = DK_UNSPECIFIED;
-
- if (context->n_classification_history > 0)
+ if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
{
- location_t location = diagnostic_location (diagnostic);
+ /* Ignore the diagnostic if all the inlined locations are
+ in system headers and -Wno-system-headers is in effect. */
+ diagnostic->kind = DK_IGNORED;
+ return DK_IGNORED;
+ }
+
+ if (context->n_classification_history <= 0)
+ return DK_UNSPECIFIED;
+ /* Iterate over the locations, checking the diagnostic disposition
+ for the diagnostic at each. If it's explicitly set as opposed
+ to unspecified, update the disposition for this instance of
+ the diagnostic and return it. */
+ for (location_t loc: diagnostic->m_iinfo.m_ilocs)
+ {
/* FIXME: Stupid search. Optimize later. */
for (int i = context->n_classification_history - 1; i >= 0; i --)
{
- if (linemap_location_before_p
- (line_table,
- context->classification_history[i].location,
- location))
+ const diagnostic_classification_change_t &hist
+ = context->classification_history[i];
+
+ location_t pragloc = hist.location;
+ if (!linemap_location_before_p (line_table, pragloc, loc))
+ continue;
+
+ if (hist.kind == (int) DK_POP)
{
- if (context->classification_history[i].kind == (int) DK_POP)
- {
- i = context->classification_history[i].option;
- continue;
- }
- int option = context->classification_history[i].option;
- /* The option 0 is for all the diagnostics. */
- if (option == 0 || option == diagnostic->option_index)
- {
- diag_class = context->classification_history[i].kind;
- if (diag_class != DK_UNSPECIFIED)
- diagnostic->kind = diag_class;
- break;
- }
+ /* Move on to the next region. */
+ i = hist.option;
+ continue;
+ }
+
+ int option = hist.option;
+ /* The option 0 is for all the diagnostics. */
+ if (option == 0 || option == diagnostic->option_index)
+ {
+ diagnostic_t kind = hist.kind;
+ if (kind != DK_UNSPECIFIED)
+ diagnostic->kind = kind;
+ return kind;
}
}
}
- return diag_class;
+ return DK_UNSPECIFIED;
}
/* Generate a URL string describing CWE. The caller is responsible for
@@ -1129,6 +1166,9 @@ static bool
diagnostic_enabled (diagnostic_context *context,
diagnostic_info *diagnostic)
{
+ /* Update the inlining stack for this diagnostic. */
+ get_any_inlining_info (context, diagnostic);
+
/* Diagnostics with no option or -fpermissive are always enabled. */
if (!diagnostic->option_index
|| diagnostic->option_index == permissive_error_option (context))
@@ -1194,9 +1234,17 @@ diagnostic_report_diagnostic (diagnostic_context *context,
/* Give preference to being able to inhibit warnings, before they
get reclassified to something else. */
- if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
- && !diagnostic_report_warnings_p (context, location))
- return false;
+ bool report_warning_p = true;
+ if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
+ {
+ if (context->dc_inhibit_warnings)
+ return false;
+ /* Remember the result of the overall system header warning setting
+ but proceed to also check the inlining context. */
+ report_warning_p = diagnostic_report_warnings_p (context, location);
+ if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
+ return false;
+ }
if (diagnostic->kind == DK_PEDWARN)
{
@@ -1204,7 +1252,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
/* We do this to avoid giving the message for -pedantic-errors. */
orig_diag_kind = diagnostic->kind;
}
-
+
if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
return false;
@@ -1228,9 +1276,19 @@ diagnostic_report_diagnostic (diagnostic_context *context,
&& diagnostic->kind == DK_WARNING)
diagnostic->kind = DK_ERROR;
+ diagnostic->message.x_data = &diagnostic->x_data;
+
+ /* Check to see if the diagnostic is enabled at the location and
+ not disabled by #pragma GCC diagnostic anywhere along the inlining
+ stack. . */
if (!diagnostic_enabled (context, diagnostic))
return false;
+ if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
+ /* Bail if the warning is not to be reported because all locations
+ in the inlining stack (if there is one) are in system headers. */
+ return false;
+
if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
diagnostic_check_max_errors (context);
@@ -1270,8 +1328,6 @@ diagnostic_report_diagnostic (diagnostic_context *context,
}
context->diagnostic_group_emission_count++;
- diagnostic->message.x_data = &diagnostic->x_data;
- diagnostic->x_data = NULL;
pp_format (context->printer, &diagnostic->message);
(*diagnostic_starter (context)) (context, diagnostic);
pp_output_formatted_text (context->printer);
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 1b9d6b1..7227dae 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -87,6 +87,11 @@ enum diagnostics_extra_output_kind
list in diagnostic.def. */
struct diagnostic_info
{
+ diagnostic_info ()
+ : message (), richloc (), metadata (), x_data (), kind (), option_index (),
+ m_iinfo ()
+ { }
+
/* Text to be formatted. */
text_info message;
@@ -103,6 +108,18 @@ struct diagnostic_info
diagnostic_t kind;
/* Which OPT_* directly controls this diagnostic. */
int option_index;
+
+ /* Inlining context containing locations for each call site along
+ the inlining stack. */
+ struct inlining_info
+ {
+ /* Locations along the inlining stack. */
+ auto_vec<location_t, 8> m_ilocs;
+ /* The abstract origin of the location. */
+ void *m_ao;
+ /* Set if every M_ILOCS element is in a system header. */
+ bool m_allsyslocs;
+ } m_iinfo;
};
/* Each time a diagnostic's classification is changed with a pragma,
@@ -136,6 +153,9 @@ struct diagnostic_context
/* Where most of the diagnostic formatting work is done. */
pretty_printer *printer;
+ /* Cache of source code. */
+ file_cache *m_file_cache;
+
/* The number of times we have issued diagnostics. */
int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
@@ -343,6 +363,12 @@ struct diagnostic_context
/* Callback for final cleanup. */
void (*final_cb) (diagnostic_context *context);
+
+ /* Callback to set the locations of call sites along the inlining
+ stack corresponding to a diagnostic location. Needed to traverse
+ the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
+ of a diagnostic's location. */
+ void (*set_locations_cb)(diagnostic_context *, diagnostic_info *);
};
static inline void
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 6493edc..e0551b4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -20726,6 +20726,9 @@ void __builtin_vsx_disassemble_pair (void *, __vector_pair *);
vec_t __builtin_vsx_xvcvspbf16 (vec_t);
vec_t __builtin_vsx_xvcvbf16spn (vec_t);
+
+__vector_pair __builtin_vsx_lxvp (size_t, __vector_pair *);
+void __builtin_vsx_stxvp (__vector_pair, size_t, __vector_pair *);
@end smallexample
@node PRU Built-in Functions
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index f7d52af..5d4c00a 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1070,6 +1070,10 @@ but for the linker.
Same as @uref{#with-as,,@option{--with-as}}
but for the linker.
+@item --with-dsymutil=@var{pathname}
+Same as @uref{#with-as,,@option{--with-as}}
+but for the debug linker (only used on Darwin platforms so far).
+
@item --with-stabs
Specify that stabs debugging
information should be used instead of whatever format the host normally
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 073dff8..733e081 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -491,7 +491,7 @@ Objective-C and Objective-C++ Dialects}.
-floop-parallelize-all -flra-remat -flto -flto-compression-level @gol
-flto-partition=@var{alg} -fmerge-all-constants @gol
-fmerge-constants -fmodulo-sched -fmodulo-sched-allow-regmoves @gol
--fmove-loop-invariants -fno-branch-count-reg @gol
+-fmove-loop-invariants -fmove-loop-stores -fno-branch-count-reg @gol
-fno-defer-pop -fno-fp-int-builtin-inexact -fno-function-cse @gol
-fno-guess-branch-probability -fno-inline -fno-math-errno -fno-peephole @gol
-fno-peephole2 -fno-printf-return-value -fno-sched-interblock @gol
@@ -10223,6 +10223,7 @@ compilation time.
-fipa-reference-addressable @gol
-fmerge-constants @gol
-fmove-loop-invariants @gol
+-fmove-loop-stores@gol
-fomit-frame-pointer @gol
-freorder-blocks @gol
-fshrink-wrap @gol
@@ -10366,7 +10367,7 @@ optimization flags except for those that may interfere with debugging:
@gccoptlist{-fbranch-count-reg -fdelayed-branch @gol
-fdse -fif-conversion -fif-conversion2 @gol
-finline-functions-called-once @gol
--fmove-loop-invariants -fssa-phiopt @gol
+-fmove-loop-invariants -fmove-loop-stores -fssa-phiopt @gol
-ftree-bit-ccp -ftree-dse -ftree-pta -ftree-sra}
@end table
@@ -12974,6 +12975,15 @@ Enabled by @option{-O3}, @option{-fprofile-use}, and @option{-fauto-profile}.
Enables the loop invariant motion pass in the RTL loop optimizer. Enabled
at level @option{-O1} and higher, except for @option{-Og}.
+@item -fmove-loop-stores
+@opindex fmove-loop-stores
+Enables the loop store motion pass in the GIMPLE loop optimizer. This
+moves invariant stores to after the end of the loop in exchange for
+carrying the stored value in a register across the iteration.
+Note for this option to have an effect @option{-ftree-loop-im} has to
+be enabled as well. Enabled at level @option{-O1} and higher, except
+for @option{-Og}.
+
@item -fsplit-loops
@opindex fsplit-loops
Split a loop into two if it contains a condition that's always true
@@ -13880,6 +13890,16 @@ of available registers reserved for some other purposes is given
by this parameter. Default of the parameter
is the best found from numerous experiments.
+@item ira-consider-dup-in-all-alts
+Make IRA to consider matching constraint (duplicated operand number)
+heavily in all available alternatives for preferred register class.
+If it is set as zero, it means IRA only respects the matching
+constraint when it's in the only available alternative with an
+appropriate register class. Otherwise, it means IRA will check all
+available alternatives for preferred register class even if it has
+found some choice with an appropriate register class and respect the
+found qualified matching constraint.
+
@item lra-inheritance-ebb-probability-cutoff
LRA tries to reuse values reloaded in registers in subsequent insns.
This optimization is called inheritance. EBB is used as a region to
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 1b91814..0fe70b7 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -5688,6 +5688,20 @@ Alternating subtract, add with even lanes doing subtract and odd
lanes doing addition. Operands 1 and 2 and the outout operand are vectors
with mode @var{m}.
+@cindex @code{vec_fmaddsub@var{m}4} instruction pattern
+@item @samp{vec_fmaddsub@var{m}4}
+Alternating multiply subtract, add with even lanes doing subtract and odd
+lanes doing addition of the third operand to the multiplication result
+of the first two operands. Operands 1, 2 and 3 and the outout operand are vectors
+with mode @var{m}.
+
+@cindex @code{vec_fmsubadd@var{m}4} instruction pattern
+@item @samp{vec_fmsubadd@var{m}4}
+Alternating multiply add, subtract with even lanes doing addition and odd
+lanes doing subtraction of the third operand to the multiplication result
+of the first two operands. Operands 1, 2 and 3 and the outout operand are vectors
+with mode @var{m}.
+
These instructions are not allowed to @code{FAIL}.
@cindex @code{mulhisi3} instruction pattern
@@ -8441,8 +8455,6 @@ list of operands, such as this example:
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")]
-@end group
-@group
""
"
@{
@@ -8459,17 +8471,10 @@ Here is an example, the definition of left-shift for the SPUR chip:
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI
-@end group
-@group
(match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
-@end group
-@end smallexample
-
-@smallexample
-@group
@{
if (GET_CODE (operands[2]) != CONST_INT
|| (unsigned) INTVAL (operands[2]) > 3)
@@ -9923,7 +9928,7 @@ Lengths are measured in addressable storage units (bytes).
Note that it is possible to call functions via the @code{symbol_ref}
mechanism to compute the length of an insn. However, if you use this
mechanism you must provide dummy clauses to express the maximum length
-without using the function call. You can an example of this in the
+without using the function call. You can see an example of this in the
@code{pa} machine description for the @code{call_symref} pattern.
The following macros can be used to refine the length computation:
diff --git a/gcc/dwarf2ctf.c b/gcc/dwarf2ctf.c
index 08e1252..5e8a725 100644
--- a/gcc/dwarf2ctf.c
+++ b/gcc/dwarf2ctf.c
@@ -100,13 +100,13 @@ ctf_get_AT_data_member_location (dw_die_ref die)
gcc_assert (!descr->dw_loc_oprnd2.v.val_unsigned);
gcc_assert (descr->dw_loc_oprnd2.val_class
== dw_val_class_unsigned_const);
- field_location = descr->dw_loc_oprnd1.v.val_unsigned;
+ field_location = descr->dw_loc_oprnd1.v.val_unsigned * 8;
}
else
{
attr = get_AT (die, DW_AT_data_member_location);
if (attr && AT_class (attr) == dw_val_class_const)
- field_location = AT_int (attr);
+ field_location = AT_int (attr) * 8;
else
field_location = (get_AT_unsigned (die,
DW_AT_data_member_location)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 13998b2..82783c4 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -19404,6 +19404,10 @@ loc_list_from_tree_1 (tree loc, int want_address,
case FIX_TRUNC_EXPR:
return 0;
+ case COMPOUND_LITERAL_EXPR:
+ return loc_list_from_tree_1 (COMPOUND_LITERAL_EXPR_DECL (loc),
+ 0, context);
+
default:
/* Leave front-end specific codes as simply unknown. This comes
up, for instance, with the C STMT_EXPR. */
diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
index 9884601..c206a25 100644
--- a/gcc/exec-tool.in
+++ b/gcc/exec-tool.in
@@ -25,6 +25,7 @@ ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
+ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@"
exeext=@host_exeext@
fast_install=@enable_fast_install@
objdir=@objdir@
@@ -71,6 +72,13 @@ case "$invoked" in
prog=nm-new$exeext
dir=binutils
;;
+ dsymutil)
+ original=$ORIGINAL_DSYMUTIL_FOR_TARGET
+ # We do not build this in tree - but still want to be able to execute
+ # a configured version from the build dir.
+ prog=
+ dir=
+ ;;
esac
case "$original" in
diff --git a/gcc/expr.c b/gcc/expr.c
index 025033c..6a43681 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7078,7 +7078,8 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
&& eltmode == GET_MODE_INNER (mode)
&& ((icode = optab_handler (vec_duplicate_optab, mode))
!= CODE_FOR_nothing)
- && (elt = uniform_vector_p (exp)))
+ && (elt = uniform_vector_p (exp))
+ && !VECTOR_TYPE_P (TREE_TYPE (elt)))
{
class expand_operand ops[2];
create_output_operand (&ops[0], target, mode);
@@ -11401,7 +11402,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
/* All valid uses of __builtin_va_arg_pack () are removed during
inlining. */
if (CALL_EXPR_VA_ARG_PACK (exp))
- error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
+ error ("invalid use of %<__builtin_va_arg_pack ()%>");
{
tree fndecl = get_callee_fndecl (exp), attr;
@@ -11413,7 +11414,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
DECL_ATTRIBUTES (fndecl))) != NULL)
{
const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
- error ("%Kcall to %qs declared with attribute error: %s", exp,
+ error ("call to %qs declared with attribute error: %s",
identifier_to_locale (ident),
TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
}
@@ -11425,10 +11426,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
DECL_ATTRIBUTES (fndecl))) != NULL)
{
const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
- warning_at (tree_nonartificial_location (exp),
+ warning_at (EXPR_LOCATION (exp),
OPT_Wattribute_warning,
- "%Kcall to %qs declared with attribute warning: %s",
- exp, identifier_to_locale (ident),
+ "call to %qs declared with attribute warning: %s",
+ identifier_to_locale (ident),
TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
}
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index dfccbae..e0cdb75 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -432,8 +432,8 @@ negate_expr_p (tree t)
return negate_expr_p (TREE_OPERAND (t, 0));
case PLUS_EXPR:
- if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- || HONOR_SIGNED_ZEROS (element_mode (type))
+ if (HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ || HONOR_SIGNED_ZEROS (type)
|| (ANY_INTEGRAL_TYPE_P (type)
&& ! TYPE_OVERFLOW_WRAPS (type)))
return false;
@@ -445,8 +445,8 @@ negate_expr_p (tree t)
case MINUS_EXPR:
/* We can't turn -(A-B) into B-A when we honor signed zeros. */
- return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- && !HONOR_SIGNED_ZEROS (element_mode (type))
+ return !HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && !HONOR_SIGNED_ZEROS (type)
&& (! ANY_INTEGRAL_TYPE_P (type)
|| TYPE_OVERFLOW_WRAPS (type));
@@ -468,7 +468,7 @@ negate_expr_p (tree t)
/* Fall through. */
case RDIV_EXPR:
- if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (TREE_TYPE (t))))
+ if (! HONOR_SIGN_DEPENDENT_ROUNDING (t))
return negate_expr_p (TREE_OPERAND (t, 1))
|| negate_expr_p (TREE_OPERAND (t, 0));
break;
@@ -605,8 +605,8 @@ fold_negate_expr_1 (location_t loc, tree t)
break;
case PLUS_EXPR:
- if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- && !HONOR_SIGNED_ZEROS (element_mode (type)))
+ if (!HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && !HONOR_SIGNED_ZEROS (type))
{
/* -(A + B) -> (-B) - A. */
if (negate_expr_p (TREE_OPERAND (t, 1)))
@@ -628,8 +628,8 @@ fold_negate_expr_1 (location_t loc, tree t)
case MINUS_EXPR:
/* - (A - B) -> B - A */
- if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- && !HONOR_SIGNED_ZEROS (element_mode (type)))
+ if (!HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && !HONOR_SIGNED_ZEROS (type))
return fold_build2_loc (loc, MINUS_EXPR, type,
TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
break;
@@ -641,7 +641,7 @@ fold_negate_expr_1 (location_t loc, tree t)
/* Fall through. */
case RDIV_EXPR:
- if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)))
+ if (! HONOR_SIGN_DEPENDENT_ROUNDING (type))
{
tem = TREE_OPERAND (t, 1);
if (negate_expr_p (tem))
@@ -1725,7 +1725,7 @@ const_unop (enum tree_code code, tree type, tree arg0)
/* Don't perform the operation, other than NEGATE and ABS, if
flag_signaling_nans is on and the operand is a signaling NaN. */
if (TREE_CODE (arg0) == REAL_CST
- && HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
+ && HONOR_SNANS (arg0)
&& REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0))
&& code != NEGATE_EXPR
&& code != ABS_EXPR
@@ -2135,7 +2135,7 @@ fold_convert_const_real_from_real (tree type, const_tree arg1)
/* Don't perform the operation if flag_signaling_nans is on
and the operand is a signaling NaN. */
- if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
+ if (HONOR_SNANS (arg1)
&& REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1)))
return NULL_TREE;
@@ -5773,7 +5773,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
Note that all these transformations are correct if A is
NaN, since the two alternatives (A and -A) are also NaNs. */
- if (!HONOR_SIGNED_ZEROS (element_mode (type))
+ if (!HONOR_SIGNED_ZEROS (type)
&& (FLOAT_TYPE_P (TREE_TYPE (arg01))
? real_zerop (arg01)
: integer_zerop (arg01))
@@ -5842,7 +5842,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
both transformations are correct when A is NaN: A != 0
is then true, and A == 0 is false. */
- if (!HONOR_SIGNED_ZEROS (element_mode (type))
+ if (!HONOR_SIGNED_ZEROS (type)
&& integer_zerop (arg01) && integer_zerop (arg2))
{
if (comp_code == NE_EXPR)
@@ -5877,7 +5877,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
a number and A is not. The conditions in the original
expressions will be false, so all four give B. The min()
and max() versions would give a NaN instead. */
- if (!HONOR_SIGNED_ZEROS (element_mode (type))
+ if (!HONOR_SIGNED_ZEROS (type)
&& operand_equal_for_comparison_p (arg01, arg2)
/* Avoid these transformations if the COND_EXPR may be used
as an lvalue in the C++ front-end. PR c++/19199. */
@@ -11005,8 +11005,8 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
/* Fold __complex__ ( x, 0 ) + __complex__ ( 0, y )
to __complex__ ( x, y ). This is not the same for SNaNs or
if signed zeros are involved. */
- if (!HONOR_SNANS (element_mode (arg0))
- && !HONOR_SIGNED_ZEROS (element_mode (arg0))
+ if (!HONOR_SNANS (arg0)
+ && !HONOR_SIGNED_ZEROS (arg0)
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
tree rtype = TREE_TYPE (TREE_TYPE (arg0));
@@ -11404,8 +11404,8 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
/* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to
__complex__ ( x, -y ). This is not the same for SNaNs or if
signed zeros are involved. */
- if (!HONOR_SNANS (element_mode (arg0))
- && !HONOR_SIGNED_ZEROS (element_mode (arg0))
+ if (!HONOR_SNANS (arg0)
+ && !HONOR_SIGNED_ZEROS (arg0)
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
tree rtype = TREE_TYPE (TREE_TYPE (arg0));
@@ -11509,7 +11509,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
This is not the same for NaNs or if signed zeros are
involved. */
if (!HONOR_NANS (arg0)
- && !HONOR_SIGNED_ZEROS (element_mode (arg0))
+ && !HONOR_SIGNED_ZEROS (arg0)
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
&& TREE_CODE (arg1) == COMPLEX_CST
&& real_zerop (TREE_REALPART (arg1)))
@@ -12819,7 +12819,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
Also try swapping the arguments and inverting the conditional. */
if (COMPARISON_CLASS_P (arg0)
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
- && !HONOR_SIGNED_ZEROS (element_mode (op1)))
+ && !HONOR_SIGNED_ZEROS (op1))
{
tem = fold_cond_expr_with_comparison (loc, type, TREE_CODE (arg0),
TREE_OPERAND (arg0, 0),
@@ -12831,7 +12831,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
if (COMPARISON_CLASS_P (arg0)
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op2)
- && !HONOR_SIGNED_ZEROS (element_mode (op2)))
+ && !HONOR_SIGNED_ZEROS (op2))
{
enum tree_code comp_code = TREE_CODE (arg0);
tree arg00 = TREE_OPERAND (arg0, 0);
@@ -14713,7 +14713,7 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
CASE_CFN_SQRT:
CASE_CFN_SQRT_FN:
/* sqrt(-0.0) is -0.0. */
- if (!HONOR_SIGNED_ZEROS (element_mode (type)))
+ if (!HONOR_SIGNED_ZEROS (type))
return true;
return RECURSE (arg0);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f9c97b0..3cf3e7d 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2021-07-06 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/100227
+ * frontend-passes.c (traverse_io_block): Adjust test for
+ when a variable is eligible for the transformation to
+ array slice.
+
2021-06-28 Martin Sebor <msebor@redhat.com>
* trans-array.c (trans_array_constructor): Replace direct uses
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 72a4e04..996dcc2 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -1299,8 +1299,8 @@ traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
std::swap (start->value.op.op1, start->value.op.op2);
gcc_fallthrough ();
case INTRINSIC_MINUS:
- if ((start->value.op.op1->expr_type!= EXPR_VARIABLE
- && start->value.op.op2->expr_type != EXPR_CONSTANT)
+ if (start->value.op.op1->expr_type!= EXPR_VARIABLE
+ || start->value.op.op2->expr_type != EXPR_CONSTANT
|| start->value.op.op1->ref)
return false;
if (!stack_top || !stack_top->iter
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 9baa7d6..12b3440 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -916,7 +916,7 @@ proper position among the other output files. */
than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
compilations. */
# define ASM_DEBUG_DWARF_OPTION ""
-# elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG)
+# elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
# define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
"%:dwarf-version-gt(3):--gdwarf-4;" \
"%:dwarf-version-gt(2):--gdwarf-3;" \
@@ -2242,7 +2242,7 @@ close_at_file (void)
if (n_args == 0)
return;
- char **argv = (char **) alloca (sizeof (char *) * (n_args + 1));
+ char **argv = XALLOCAVEC (char *, n_args + 1);
char *temp_file = make_at_file ();
char *at_argument = concat ("@", temp_file, NULL);
FILE *f = fopen (temp_file, "w");
@@ -3062,6 +3062,11 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
return xstrdup (DEFAULT_LINKER);
#endif
+#ifdef DEFAULT_DSYMUTIL
+ if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, mode) == 0)
+ return xstrdup (DEFAULT_DSYMUTIL);
+#endif
+
/* Determine the filename to execute (special case for absolute paths). */
if (IS_ABSOLUTE_PATH (name))
@@ -3251,7 +3256,7 @@ execute (void)
n_commands++;
/* Get storage for each command. */
- commands = (struct command *) alloca (n_commands * sizeof (struct command));
+ commands = XALLOCAVEC (struct command, n_commands);
/* Split argbuf into its separate piped processes,
and record info about each one.
@@ -3430,13 +3435,13 @@ execute (void)
struct pex_time *times = NULL;
int ret_code = 0;
- statuses = (int *) alloca (n_commands * sizeof (int));
+ statuses = XALLOCAVEC (int, n_commands);
if (!pex_get_status (pex, n_commands, statuses))
fatal_error (input_location, "failed to get exit status: %m");
if (report_times || report_times_to_file)
{
- times = (struct pex_time *) alloca (n_commands * sizeof (struct pex_time));
+ times = XALLOCAVEC (struct pex_time, n_commands);
if (!pex_get_times (pex, n_commands, times))
fatal_error (input_location, "failed to get process times: %m");
}
@@ -3752,6 +3757,7 @@ display_help (void)
fputs (_(" -dumpspecs Display all of the built in spec strings.\n"), stdout);
fputs (_(" -dumpversion Display the version of the compiler.\n"), stdout);
fputs (_(" -dumpmachine Display the compiler's target processor.\n"), stdout);
+ fputs (_(" -foffload=<targets> Specify offloading targets.\n"), stdout);
fputs (_(" -print-search-dirs Display the directories in the compiler's search path.\n"), stdout);
fputs (_(" -print-libgcc-file-name Display the name of the compiler's companion library.\n"), stdout);
fputs (_(" -print-file-name=<lib> Display the full path to library <lib>.\n"), stdout);
@@ -3995,31 +4001,32 @@ check_offload_target_name (const char *target, ptrdiff_t len)
}
if (!c)
{
- char *s;
auto_vec<const char*> candidates;
- char *cand = (char *) alloca (strlen (OFFLOAD_TARGETS) + 1);
- c = OFFLOAD_TARGETS;
- while (c)
+ size_t olen = strlen (OFFLOAD_TARGETS) + 1;
+ char *cand = XALLOCAVEC (char, olen);
+ memcpy (cand, OFFLOAD_TARGETS, olen);
+ for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
+ candidates.safe_push (c);
+
+ char *target2 = XALLOCAVEC (char, len + 1);
+ memcpy (target2, target, len);
+ target2[len] = '\0';
+
+ error ("GCC is not configured to support %qs as offload target", target2);
+
+ if (candidates.is_empty ())
+ inform (UNKNOWN_LOCATION, "no offloading targets configured");
+ else
{
- n = strchr (c, ',');
- if (n == NULL)
- n = strchr (c, '\0');
- if (n - c == 0)
- break;
- strncpy (cand, c, n - c);
- cand[n - c] = '\0';
- candidates.safe_push (cand);
- c = *n ? n + 1 : NULL;
+ char *s;
+ const char *hint = candidates_list_and_hint (target2, s, candidates);
+ if (hint)
+ inform (UNKNOWN_LOCATION,
+ "valid offload targets are: %s; did you mean %qs?", s, hint);
+ else
+ inform (UNKNOWN_LOCATION, "valid offload targets are: %s", s);
+ XDELETEVEC (s);
}
- error ("GCC is not configured to support %q.*s as offload target",
- (int) len, target);
- const char *hint = candidates_list_and_hint (target, s, candidates);
- if (hint)
- inform (UNKNOWN_LOCATION,
- "valid offload targets are: %s; did you mean %qs?", s, hint);
- else
- inform (UNKNOWN_LOCATION, "valid offload targets are: %s", s);
- XDELETEVEC (s);
return false;
}
return true;
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index 63fac0c..9d9715f 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -110,7 +110,7 @@ process_define_predicate (md_rtx_info *info)
becomes
- static inline int basereg_operand_1(rtx op, machine_mode mode)
+ static inline bool basereg_operand_1(rtx op, machine_mode mode)
{
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -151,7 +151,7 @@ write_predicate_subfunction (struct pred_data *p)
p->exp = and_exp;
- printf ("static inline int\n"
+ printf ("static inline bool\n"
"%s_1 (rtx op ATTRIBUTE_UNUSED, machine_mode mode ATTRIBUTE_UNUSED)\n",
p->name);
rtx_reader_ptr->print_md_ptr_loc (p->c_block);
@@ -651,7 +651,7 @@ write_one_predicate_function (struct pred_data *p)
/* A normal predicate can legitimately not look at machine_mode
if it accepts only CONST_INTs and/or CONST_WIDE_INT and/or CONST_DOUBLEs. */
- printf ("int\n%s (rtx op, machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
+ printf ("bool\n%s (rtx op, machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
p->name);
write_predicate_stmts (p->exp);
fputs ("}\n\n", stdout);
@@ -1416,7 +1416,7 @@ write_tm_preds_h (void)
#ifdef HAVE_MACHINE_MODES");
FOR_ALL_PREDICATES (p)
- printf ("extern int %s (rtx, machine_mode);\n", p->name);
+ printf ("extern bool %s (rtx, machine_mode);\n", p->name);
puts ("#endif /* HAVE_MACHINE_MODES */\n");
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 13f0868..8dfd6f9 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -414,269 +414,72 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
if (warning_suppressed_p (ref, OPT_Warray_bounds))
return false;
- tree arg = TREE_OPERAND (ref, 0);
- /* The constant and variable offset of the reference. */
- tree cstoff = TREE_OPERAND (ref, 1);
- tree varoff = NULL_TREE;
-
- const offset_int maxobjsize = tree_to_shwi (max_object_size ());
-
- /* The zero-based array or string constant bounds in bytes. Initially
- set to [-MAXOBJSIZE - 1, MAXOBJSIZE] until a tighter bound is
- determined. */
- offset_int arrbounds[2] = { -maxobjsize - 1, maxobjsize };
-
- /* The minimum and maximum intermediate offset. For a reference
- to be valid, not only does the final offset/subscript must be
- in bounds but all intermediate offsets should be as well.
- GCC may be able to deal gracefully with such out-of-bounds
- offsets so the checking is only enabled at -Warray-bounds=2
- where it may help detect bugs in uses of the intermediate
- offsets that could otherwise not be detectable. */
- offset_int ioff = wi::to_offset (fold_convert (ptrdiff_type_node, cstoff));
- offset_int extrema[2] = { 0, wi::abs (ioff) };
-
- /* The range of the byte offset into the reference. */
- offset_int offrange[2] = { 0, 0 };
-
/* The statement used to allocate the array or null. */
gimple *alloc_stmt = NULL;
/* For an allocation statement, the low bound of the size range. */
offset_int minbound = 0;
+ /* The type and size of the access. */
+ tree axstype = TREE_TYPE (ref);
+ offset_int axssize = 0;
+ if (TREE_CODE (axstype) != UNION_TYPE)
+ if (tree access_size = TYPE_SIZE_UNIT (axstype))
+ if (TREE_CODE (access_size) == INTEGER_CST)
+ axssize = wi::to_offset (access_size);
- /* Determine the offsets and increment OFFRANGE for the bounds of each.
- The loop computes the range of the final offset for expressions such
- as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in
- some range. */
- const unsigned limit = param_ssa_name_def_chain_limit;
- for (unsigned n = 0; TREE_CODE (arg) == SSA_NAME && n < limit; ++n)
- {
- gimple *def = SSA_NAME_DEF_STMT (arg);
- if (is_gimple_call (def))
- {
- /* Determine the byte size of the array from an allocation call. */
- wide_int sizrng[2];
- if (gimple_call_alloc_size (def, sizrng))
- {
- arrbounds[0] = 0;
- arrbounds[1] = offset_int::from (sizrng[1], UNSIGNED);
- minbound = offset_int::from (sizrng[0], UNSIGNED);
- alloc_stmt = def;
- }
- break;
- }
-
- if (gimple_nop_p (def))
- {
- /* For a function argument try to determine the byte size
- of the array from the current function declaratation
- (e.g., attribute access or related). */
- wide_int wr[2];
- tree ref = gimple_parm_array_size (arg, wr);
- if (!ref)
- break;
- arrbounds[0] = offset_int::from (wr[0], UNSIGNED);
- arrbounds[1] = offset_int::from (wr[1], UNSIGNED);
- arg = ref;
- break;
- }
-
- if (!is_gimple_assign (def))
- break;
-
- tree_code code = gimple_assign_rhs_code (def);
- if (code == POINTER_PLUS_EXPR)
- {
- arg = gimple_assign_rhs1 (def);
- varoff = gimple_assign_rhs2 (def);
- }
- else if (code == ASSERT_EXPR)
- {
- arg = TREE_OPERAND (gimple_assign_rhs1 (def), 0);
- continue;
- }
- else
- return false;
-
- /* VAROFF should always be a SSA_NAME here (and not even
- INTEGER_CST) but there's no point in taking chances. */
- if (TREE_CODE (varoff) != SSA_NAME)
- break;
-
- const value_range* const vr = get_value_range (varoff);
- if (!vr || vr->undefined_p () || vr->varying_p ())
- break;
-
- if (!vr->constant_p ())
- break;
-
- if (vr->kind () == VR_RANGE)
- {
- offset_int min
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
- offset_int max
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
- if (min < max)
- {
- offrange[0] += min;
- offrange[1] += max;
- }
- else
- {
- /* When MIN >= MAX, the offset is effectively in a union
- of two ranges: [-MAXOBJSIZE -1, MAX] and [MIN, MAXOBJSIZE].
- Since there is no way to represent such a range across
- additions, conservatively add [-MAXOBJSIZE -1, MAXOBJSIZE]
- to OFFRANGE. */
- offrange[0] += arrbounds[0];
- offrange[1] += arrbounds[1];
- }
- }
- else
- {
- /* For an anti-range, analogously to the above, conservatively
- add [-MAXOBJSIZE -1, MAXOBJSIZE] to OFFRANGE. */
- offrange[0] += arrbounds[0];
- offrange[1] += arrbounds[1];
- }
-
- /* Keep track of the minimum and maximum offset. */
- if (offrange[1] < 0 && offrange[1] < extrema[0])
- extrema[0] = offrange[1];
- if (offrange[0] > 0 && offrange[0] > extrema[1])
- extrema[1] = offrange[0];
-
- if (offrange[0] < arrbounds[0])
- offrange[0] = arrbounds[0];
-
- if (offrange[1] > arrbounds[1])
- offrange[1] = arrbounds[1];
- }
+ access_ref aref;
+ if (!compute_objsize (ref, 0, &aref, ranges))
+ return false;
- tree reftype = NULL_TREE;
- offset_int eltsize = -1;
- if (arrbounds[0] >= 0)
- {
- /* The byte size of the array has already been determined above
- based on a pointer ARG. Set ELTSIZE to the size of the type
- it points to and REFTYPE to the array with the size, rounded
- down as necessary. */
- reftype = TREE_TYPE (TREE_TYPE (arg));
- if (TREE_CODE (reftype) == ARRAY_TYPE)
- reftype = TREE_TYPE (reftype);
- if (tree refsize = TYPE_SIZE_UNIT (reftype))
- if (TREE_CODE (refsize) == INTEGER_CST)
- eltsize = wi::to_offset (refsize);
-
- if (eltsize < 0)
- return false;
+ if (aref.offset_in_range (axssize))
+ return false;
- offset_int nelts = arrbounds[1] / eltsize;
- reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
- }
- else if (TREE_CODE (arg) == ADDR_EXPR)
+ if (TREE_CODE (aref.ref) == SSA_NAME)
{
- arg = TREE_OPERAND (arg, 0);
- if (TREE_CODE (arg) != STRING_CST
- && TREE_CODE (arg) != PARM_DECL
- && TREE_CODE (arg) != VAR_DECL)
- return false;
-
- /* The type of the object being referred to. It can be an array,
- string literal, or a non-array type when the MEM_REF represents
- a reference/subscript via a pointer to an object that is not
- an element of an array. Incomplete types are excluded as well
- because their size is not known. */
- reftype = TREE_TYPE (arg);
- if (POINTER_TYPE_P (reftype)
- || !COMPLETE_TYPE_P (reftype)
- || TREE_CODE (TYPE_SIZE_UNIT (reftype)) != INTEGER_CST)
- return false;
-
- /* Except in declared objects, references to trailing array members
- of structs and union objects are excluded because MEM_REF doesn't
- make it possible to identify the member where the reference
- originated. */
- if (RECORD_OR_UNION_TYPE_P (reftype)
- && (!VAR_P (arg)
- || (DECL_EXTERNAL (arg) && array_at_struct_end_p (ref))))
- return false;
-
- /* FIXME: Should this be 1 for Fortran? */
- arrbounds[0] = 0;
-
- if (TREE_CODE (reftype) == ARRAY_TYPE)
- {
- /* Set to the size of the array element (and adjust below). */
- eltsize = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (reftype)));
- /* Use log2 of size to convert the array byte size in to its
- upper bound in elements. */
- const offset_int eltsizelog2 = wi::floor_log2 (eltsize);
- if (tree dom = TYPE_DOMAIN (reftype))
- {
- tree bnds[] = { TYPE_MIN_VALUE (dom), TYPE_MAX_VALUE (dom) };
- if (TREE_CODE (arg) == COMPONENT_REF)
- {
- offset_int size = maxobjsize;
- if (tree fldsize = component_ref_size (arg))
- size = wi::to_offset (fldsize);
- arrbounds[1] = wi::lrshift (size, eltsizelog2);
- }
- else if (array_at_struct_end_p (arg) || !bnds[0] || !bnds[1])
- arrbounds[1] = wi::lrshift (maxobjsize, eltsizelog2);
- else
- arrbounds[1] = (wi::to_offset (bnds[1]) - wi::to_offset (bnds[0])
- + 1) * eltsize;
- }
- else
- arrbounds[1] = wi::lrshift (maxobjsize, eltsizelog2);
-
- /* Determine a tighter bound of the non-array element type. */
- tree eltype = TREE_TYPE (reftype);
- while (TREE_CODE (eltype) == ARRAY_TYPE)
- eltype = TREE_TYPE (eltype);
- eltsize = wi::to_offset (TYPE_SIZE_UNIT (eltype));
- }
- else
+ gimple *def = SSA_NAME_DEF_STMT (aref.ref);
+ if (is_gimple_call (def))
{
- eltsize = 1;
- tree size = TYPE_SIZE_UNIT (reftype);
- if (VAR_P (arg))
- if (tree initsize = DECL_SIZE_UNIT (arg))
- if (tree_int_cst_lt (size, initsize))
- size = initsize;
-
- arrbounds[1] = wi::to_offset (size);
+ /* Save the allocation call and the low bound on the size. */
+ alloc_stmt = def;
+ minbound = aref.sizrng[0];
}
}
- else
- return false;
-
- offrange[0] += ioff;
- offrange[1] += ioff;
+
+ /* The range of the byte offset into the reference. Adjusted below. */
+ offset_int offrange[2] = { aref.offrng[0], aref.offrng[1] };
+
+ /* The type of the referenced object. */
+ tree reftype = TREE_TYPE (aref.ref);
+ /* The size of the referenced array element. */
+ offset_int eltsize = 1;
+ /* The byte size of the array has already been determined above
+ based on a pointer ARG. Set ELTSIZE to the size of the type
+ it points to and REFTYPE to the array with the size, rounded
+ down as necessary. */
+ if (POINTER_TYPE_P (reftype))
+ reftype = TREE_TYPE (reftype);
+ if (TREE_CODE (reftype) == ARRAY_TYPE)
+ reftype = TREE_TYPE (reftype);
+ if (tree refsize = TYPE_SIZE_UNIT (reftype))
+ if (TREE_CODE (refsize) == INTEGER_CST)
+ eltsize = wi::to_offset (refsize);
+
+ const offset_int nelts = aref.sizrng[1] / eltsize;
+ reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
/* Compute the more permissive upper bound when IGNORE_OFF_BY_ONE
is set (when taking the address of the one-past-last element
of an array) but always use the stricter bound in diagnostics. */
- offset_int ubound = arrbounds[1];
+ offset_int ubound = aref.sizrng[1];
if (ignore_off_by_one)
ubound += eltsize;
- bool warned = false;
/* Set if the lower bound of the subscript is out of bounds. */
- const bool lboob = (arrbounds[0] == arrbounds[1]
+ const bool lboob = (aref.sizrng[1] == 0
|| offrange[0] >= ubound
- || offrange[1] < arrbounds[0]);
+ || offrange[1] < 0);
/* Set if only the upper bound of the subscript is out of bounds.
This can happen when using a bigger type to index into an array
of a smaller type, as is common with unsigned char. */
- tree axstype = TREE_TYPE (ref);
- offset_int axssize = 0;
- if (TREE_CODE (axstype) != UNION_TYPE)
- if (tree access_size = TYPE_SIZE_UNIT (axstype))
- if (TREE_CODE (access_size) == INTEGER_CST)
- axssize = wi::to_offset (access_size);
-
const bool uboob = !lboob && offrange[0] + axssize > ubound;
if (lboob || uboob)
{
@@ -689,9 +492,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
to compute the index to print in the diagnostic; arrays
in MEM_REF don't mean anything. A type with no size like
void is as good as having a size of 1. */
- tree type = TREE_TYPE (ref);
- while (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
+ tree type = strip_array_types (TREE_TYPE (ref));
if (tree size = TYPE_SIZE_UNIT (type))
{
offrange[0] = offrange[0] / wi::to_offset (size);
@@ -699,6 +500,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
}
}
+ bool warned = false;
if (lboob)
{
if (offrange[0] == offrange[1])
@@ -720,7 +522,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
/* If the memory was dynamically allocated refer to it as if
it were an untyped array of bytes. */
backtype = build_array_type_nelts (unsigned_char_type_node,
- arrbounds[1].to_uhwi ());
+ aref.sizrng[1].to_uhwi ());
warned = warning_at (location, OPT_Warray_bounds,
"array subscript %<%T[%wi]%> is partly "
@@ -730,46 +532,8 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
if (warned)
{
- if (DECL_P (arg))
- inform (DECL_SOURCE_LOCATION (arg), "while referencing %qD", arg);
- else if (alloc_stmt)
- {
- location_t loc = gimple_location (alloc_stmt);
- if (gimple_call_builtin_p (alloc_stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
- {
- if (minbound == arrbounds[1])
- inform (loc, "referencing a variable length array "
- "of size %wu", minbound.to_uhwi ());
- else
- inform (loc, "referencing a variable length array "
- "of size between %wu and %wu",
- minbound.to_uhwi (), arrbounds[1].to_uhwi ());
- }
- else if (tree fndecl = gimple_call_fndecl (alloc_stmt))
- {
- if (minbound == arrbounds[1])
- inform (loc, "referencing an object of size %wu "
- "allocated by %qD",
- minbound.to_uhwi (), fndecl);
- else
- inform (loc, "referencing an object of size between "
- "%wu and %wu allocated by %qD",
- minbound.to_uhwi (), arrbounds[1].to_uhwi (), fndecl);
- }
- else
- {
- tree fntype = gimple_call_fntype (alloc_stmt);
- if (minbound == arrbounds[1])
- inform (loc, "referencing an object of size %wu "
- "allocated by %qT",
- minbound.to_uhwi (), fntype);
- else
- inform (loc, "referencing an object of size between "
- "%wu and %wu allocated by %qT",
- minbound.to_uhwi (), arrbounds[1].to_uhwi (), fntype);
- }
- }
-
+ /* TODO: Determine the access from the statement and use it. */
+ aref.inform_access (access_none);
suppress_warning (ref, OPT_Warray_bounds);
return true;
}
@@ -779,9 +543,9 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
/* At level 2 check also intermediate offsets. */
int i = 0;
- if (extrema[i] < -arrbounds[1] || extrema[i = 1] > ubound)
+ if (aref.offmax[i] < -aref.sizrng[1] || aref.offmax[i = 1] > ubound)
{
- HOST_WIDE_INT tmpidx = extrema[i].to_shwi () / eltsize.to_shwi ();
+ HOST_WIDE_INT tmpidx = aref.offmax[i].to_shwi () / eltsize.to_shwi ();
if (warning_at (location, OPT_Warray_bounds,
"intermediate array offset %wi is outside array bounds "
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 6803153..1401092 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2115,13 +2115,13 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
tree slen = get_maxval_strlen (src, SRK_STRLEN);
if (slen && !integer_zerop (slen))
warning_at (loc, OPT_Wstringop_truncation,
- "%G%qD destination unchanged after copying no bytes "
+ "%qD destination unchanged after copying no bytes "
"from a string of length %E",
- stmt, fndecl, slen);
+ fndecl, slen);
else
warning_at (loc, OPT_Wstringop_truncation,
- "%G%qD destination unchanged after copying no bytes",
- stmt, fndecl);
+ "%qD destination unchanged after copying no bytes",
+ fndecl);
}
replace_call_with_value (gsi, dest);
@@ -2498,11 +2498,11 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
location_t loc = gimple_location (stmt);
nowarn = warning_at (loc, OPT_Wstringop_overflow_,
cmpdst == 0
- ? G_("%G%qD specified bound %E equals "
+ ? G_("%qD specified bound %E equals "
"destination size")
- : G_("%G%qD specified bound %E exceeds "
+ : G_("%qD specified bound %E exceeds "
"destination size %wu"),
- stmt, fndecl, len, dstsize);
+ fndecl, len, dstsize);
if (nowarn)
suppress_warning (stmt, OPT_Wstringop_overflow_);
}
@@ -2518,8 +2518,8 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
of the destination is unknown (it's not an uncommon mistake
to specify as the bound to strncpy the length of the source). */
if (warning_at (loc, OPT_Wstringop_overflow_,
- "%G%qD specified bound %E equals source length",
- stmt, fndecl, len))
+ "%qD specified bound %E equals source length",
+ fndecl, len))
suppress_warning (stmt, OPT_Wstringop_overflow_);
}
diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index 43045c54..7a88faa 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -1043,8 +1043,11 @@ tree_loop_interchange::valid_data_dependences (unsigned i_idx, unsigned o_idx,
continue;
/* Be conservative, skip case if either direction at i_idx/o_idx
- levels is not '=' (for the inner loop) or '<'. */
- if (dist_vect[i_idx] < 0 || dist_vect[o_idx] <= 0)
+ levels is not '=' or '<'. */
+ if ((!DDR_REVERSED_P (ddr) && dist_vect[i_idx] < 0)
+ || (DDR_REVERSED_P (ddr) && dist_vect[i_idx] > 0)
+ || (!DDR_REVERSED_P (ddr) && dist_vect[o_idx] < 0)
+ || (DDR_REVERSED_P (ddr) && dist_vect[o_idx] > 0))
return false;
}
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 8be4041..39c5775 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -3059,23 +3059,6 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
}
-
-/* Handle the %G format for TEXT. Same as %K in handle_K_format in
- tree-pretty-print.c but with a Gimple statement as an argument. */
-
-void
-percent_G_format (text_info *text)
-{
- gimple *stmt = va_arg (*text->args_ptr, gimple*);
-
- /* Fall back on the rich location if the statement doesn't have one. */
- location_t loc = gimple_location (stmt);
- if (loc == UNKNOWN_LOCATION)
- loc = text->m_richloc->get_loc ();
- tree block = gimple_block (stmt);
- percent_K_format (text, loc, block);
-}
-
#if __GNUC__ >= 10
# pragma GCC diagnostic pop
#endif
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 41e3be6..f38fb03 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -3115,9 +3115,8 @@ format_directive (const call_info &info,
if (fmtres.nullp)
{
fmtwarn (dirloc, argloc, NULL, info.warnopt (),
- "%G%<%.*s%> directive argument is null",
- info.callstmt, dirlen,
- target_to_host (hostdir, sizeof hostdir, dir.beg));
+ "%<%.*s%> directive argument is null",
+ dirlen, target_to_host (hostdir, sizeof hostdir, dir.beg));
/* Don't bother processing the rest of the format string. */
res->warned = true;
@@ -4620,8 +4619,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry)
is not constant. */
location_t loc = gimple_location (info.callstmt);
warning_at (EXPR_LOC_OR_LOC (dstptr, loc),
- info.warnopt (), "%Gnull destination pointer",
- info.callstmt);
+ info.warnopt (), "null destination pointer");
return false;
}
@@ -4650,8 +4648,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry)
{
location_t loc = gimple_location (info.callstmt);
warning_at (EXPR_LOC_OR_LOC (info.format, loc),
- info.warnopt (), "%Gnull format string",
- info.callstmt);
+ info.warnopt (), "null format string");
return false;
}
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index 72480f1..4fc7125 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -283,7 +283,7 @@ pass_walloca::execute (function *fun)
}
else if (warn_alloca)
{
- warning_at (loc, OPT_Walloca, "%Guse of %<alloca%>", stmt);
+ warning_at (loc, OPT_Walloca, "use of %<alloca%>");
continue;
}
else if (warn_alloca_limit < 0)
@@ -322,11 +322,10 @@ pass_walloca::execute (function *fun)
auto_diagnostic_group d;
if (warning_at (loc, wcode,
(is_vla
- ? G_("%Gargument to variable-length "
+ ? G_("argument to variable-length "
"array may be too large")
- : G_("%Gargument to %<alloca%> may be too "
- "large")),
- stmt)
+ : G_("argument to %<alloca%> may be too "
+ "large")))
&& t.limit != 0)
{
print_decu (t.limit, buff);
@@ -342,10 +341,9 @@ pass_walloca::execute (function *fun)
auto_diagnostic_group d;
if (warning_at (loc, wcode,
(is_vla
- ? G_("%Gargument to variable-length"
+ ? G_("argument to variable-length"
" array is too large")
- : G_("%Gargument to %<alloca%> is too large")),
- stmt)
+ : G_("argument to %<alloca%> is too large")))
&& t.limit != 0)
{
print_decu (t.limit, buff);
@@ -361,22 +359,20 @@ pass_walloca::execute (function *fun)
warning_at (loc, wcode,
(is_vla
- ? G_("%Gunbounded use of variable-length array")
- : G_("%Gunbounded use of %<alloca%>")),
- stmt);
+ ? G_("unbounded use of variable-length array")
+ : G_("unbounded use of %<alloca%>")));
break;
case ALLOCA_IN_LOOP:
gcc_assert (!is_vla);
warning_at (loc, wcode,
- "%Guse of %<alloca%> within a loop", stmt);
+ "use of %<alloca%> within a loop");
break;
case ALLOCA_ARG_IS_ZERO:
warning_at (loc, wcode,
(is_vla
- ? G_("%Gargument to variable-length array "
+ ? G_("argument to variable-length array "
"is zero")
- : G_("%Gargument to %<alloca%> is zero")),
- stmt);
+ : G_("argument to %<alloca%> is zero")));
break;
default:
gcc_unreachable ();
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 02771e4..efb8db9 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1494,36 +1494,36 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
warning_at (loc, OPT_Wrestrict,
sizrange[0] == 1
? (ovlsiz[0] == 1
- ? G_("%G%qD accessing %wu byte at offsets %s "
+ ? G_("%qD accessing %wu byte at offsets %s "
"and %s overlaps %wu byte at offset %s")
- : G_("%G%qD accessing %wu byte at offsets %s "
+ : G_("%qD accessing %wu byte at offsets %s "
"and %s overlaps %wu bytes at offset "
"%s"))
: (ovlsiz[0] == 1
- ? G_("%G%qD accessing %wu bytes at offsets %s "
+ ? G_("%qD accessing %wu bytes at offsets %s "
"and %s overlaps %wu byte at offset %s")
- : G_("%G%qD accessing %wu bytes at offsets %s "
+ : G_("%qD accessing %wu bytes at offsets %s "
"and %s overlaps %wu bytes at offset "
"%s")),
- call, func, sizrange[0],
+ func, sizrange[0],
offstr[0], offstr[1], ovlsiz[0], offstr[2]);
else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
warning_n (loc, OPT_Wrestrict, sizrange[0],
- "%G%qD accessing %wu byte at offsets %s "
+ "%qD accessing %wu byte at offsets %s "
"and %s overlaps between %wu and %wu bytes "
"at offset %s",
- "%G%qD accessing %wu bytes at offsets %s "
+ "%qD accessing %wu bytes at offsets %s "
"and %s overlaps between %wu and %wu bytes "
"at offset %s",
- call, func, sizrange[0], offstr[0], offstr[1],
+ func, sizrange[0], offstr[0], offstr[1],
ovlsiz[0], ovlsiz[1], offstr[2]);
else
warning_n (loc, OPT_Wrestrict, sizrange[0],
- "%G%qD accessing %wu byte at offsets %s and "
+ "%qD accessing %wu byte at offsets %s and "
"%s overlaps %wu or more bytes at offset %s",
- "%G%qD accessing %wu bytes at offsets %s and "
+ "%qD accessing %wu bytes at offsets %s and "
"%s overlaps %wu or more bytes at offset %s",
- call, func, sizrange[0],
+ func, sizrange[0],
offstr[0], offstr[1], ovlsiz[0], offstr[2]);
return true;
}
@@ -1532,28 +1532,28 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
{
if (ovlsiz[0] == ovlsiz[1])
warning_n (loc, OPT_Wrestrict, ovlsiz[0],
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"at offsets %s and %s overlaps %wu byte at "
"offset %s",
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"at offsets %s and %s overlaps %wu bytes "
"at offset %s",
- call, func, sizrange[0], sizrange[1],
+ func, sizrange[0], sizrange[1],
offstr[0], offstr[1], ovlsiz[0], offstr[2]);
else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
warning_at (loc, OPT_Wrestrict,
- "%G%qD accessing between %wu and %wu bytes at "
+ "%qD accessing between %wu and %wu bytes at "
"offsets %s and %s overlaps between %wu and %wu "
"bytes at offset %s",
- call, func, sizrange[0], sizrange[1],
+ func, sizrange[0], sizrange[1],
offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
offstr[2]);
else
warning_at (loc, OPT_Wrestrict,
- "%G%qD accessing between %wu and %wu bytes at "
+ "%qD accessing between %wu and %wu bytes at "
"offsets %s and %s overlaps %wu or more bytes "
"at offset %s",
- call, func, sizrange[0], sizrange[1],
+ func, sizrange[0], sizrange[1],
offstr[0], offstr[1], ovlsiz[0], offstr[2]);
return true;
}
@@ -1563,24 +1563,24 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
if (ovlsiz[0] == ovlsiz[1])
warning_n (loc, OPT_Wrestrict, ovlsiz[0],
- "%G%qD accessing %wu or more bytes at offsets "
+ "%qD accessing %wu or more bytes at offsets "
"%s and %s overlaps %wu byte at offset %s",
- "%G%qD accessing %wu or more bytes at offsets "
+ "%qD accessing %wu or more bytes at offsets "
"%s and %s overlaps %wu bytes at offset %s",
- call, func, sizrange[0], offstr[0], offstr[1],
+ func, sizrange[0], offstr[0], offstr[1],
ovlsiz[0], offstr[2]);
else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
warning_at (loc, OPT_Wrestrict,
- "%G%qD accessing %wu or more bytes at offsets %s "
+ "%qD accessing %wu or more bytes at offsets %s "
"and %s overlaps between %wu and %wu bytes "
"at offset %s",
- call, func, sizrange[0], offstr[0], offstr[1],
+ func, sizrange[0], offstr[0], offstr[1],
ovlsiz[0], ovlsiz[1], offstr[2]);
else
warning_at (loc, OPT_Wrestrict,
- "%G%qD accessing %wu or more bytes at offsets %s "
+ "%qD accessing %wu or more bytes at offsets %s "
"and %s overlaps %wu or more bytes at offset %s",
- call, func, sizrange[0], offstr[0], offstr[1],
+ func, sizrange[0], offstr[0], offstr[1],
ovlsiz[0], offstr[2]);
return true;
}
@@ -1606,36 +1606,36 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
{
if (open_range)
warning_n (loc, OPT_Wrestrict, sizrange[1],
- "%G%qD accessing %wu byte may overlap "
+ "%qD accessing %wu byte may overlap "
"%wu byte",
- "%G%qD accessing %wu bytes may overlap "
+ "%qD accessing %wu bytes may overlap "
"%wu byte",
- call, func, sizrange[1], ovlsiz[1]);
+ func, sizrange[1], ovlsiz[1]);
else
warning_n (loc, OPT_Wrestrict, sizrange[1],
- "%G%qD accessing %wu byte at offsets %s "
+ "%qD accessing %wu byte at offsets %s "
"and %s may overlap %wu byte at offset %s",
- "%G%qD accessing %wu bytes at offsets %s "
+ "%qD accessing %wu bytes at offsets %s "
"and %s may overlap %wu byte at offset %s",
- call, func, sizrange[1], offstr[0], offstr[1],
+ func, sizrange[1], offstr[0], offstr[1],
ovlsiz[1], offstr[2]);
return true;
}
if (open_range)
warning_n (loc, OPT_Wrestrict, sizrange[1],
- "%G%qD accessing %wu byte may overlap "
+ "%qD accessing %wu byte may overlap "
"up to %wu bytes",
- "%G%qD accessing %wu bytes may overlap "
+ "%qD accessing %wu bytes may overlap "
"up to %wu bytes",
- call, func, sizrange[1], ovlsiz[1]);
+ func, sizrange[1], ovlsiz[1]);
else
warning_n (loc, OPT_Wrestrict, sizrange[1],
- "%G%qD accessing %wu byte at offsets %s and "
+ "%qD accessing %wu byte at offsets %s and "
"%s may overlap up to %wu bytes at offset %s",
- "%G%qD accessing %wu bytes at offsets %s and "
+ "%qD accessing %wu bytes at offsets %s and "
"%s may overlap up to %wu bytes at offset %s",
- call, func, sizrange[1], offstr[0], offstr[1],
+ func, sizrange[1], offstr[0], offstr[1],
ovlsiz[1], offstr[2]);
return true;
}
@@ -1644,30 +1644,30 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
{
if (open_range)
warning_n (loc, OPT_Wrestrict, ovlsiz[1],
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"may overlap %wu byte",
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"may overlap up to %wu bytes",
- call, func, sizrange[0], sizrange[1], ovlsiz[1]);
+ func, sizrange[0], sizrange[1], ovlsiz[1]);
else
warning_n (loc, OPT_Wrestrict, ovlsiz[1],
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"at offsets %s and %s may overlap %wu byte "
"at offset %s",
- "%G%qD accessing between %wu and %wu bytes "
+ "%qD accessing between %wu and %wu bytes "
"at offsets %s and %s may overlap up to %wu "
"bytes at offset %s",
- call, func, sizrange[0], sizrange[1],
+ func, sizrange[0], sizrange[1],
offstr[0], offstr[1], ovlsiz[1], offstr[2]);
return true;
}
warning_n (loc, OPT_Wrestrict, ovlsiz[1],
- "%G%qD accessing %wu or more bytes at offsets %s "
+ "%qD accessing %wu or more bytes at offsets %s "
"and %s may overlap %wu byte at offset %s",
- "%G%qD accessing %wu or more bytes at offsets %s "
+ "%qD accessing %wu or more bytes at offsets %s "
"and %s may overlap up to %wu bytes at offset %s",
- call, func, sizrange[0], offstr[0], offstr[1],
+ func, sizrange[0], offstr[0], offstr[1],
ovlsiz[1], offstr[2]);
return true;
@@ -1689,7 +1689,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
const builtin_memref &ref, offset_int wroff,
bool do_warn)
{
- location_t loc = gimple_or_expr_nonartificial_location (call, ref.ptr);
+ location_t loc = gimple_location (call);
const offset_int maxobjsize = ref.maxobjsize;
/* Check for excessive size first and regardless of warning options
@@ -1709,15 +1709,15 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
{
if (ref.sizrange[0] == ref.sizrange[1])
warned = warning_at (loc, opt,
- "%G%qD specified bound %wu "
+ "%qD specified bound %wu "
"exceeds maximum object size %wu",
- call, func, ref.sizrange[0].to_uhwi (),
+ func, ref.sizrange[0].to_uhwi (),
maxobjsize.to_uhwi ());
else
warned = warning_at (loc, opt,
- "%G%qD specified bound between %wu and %wu "
+ "%qD specified bound between %wu and %wu "
"exceeds maximum object size %wu",
- call, func, ref.sizrange[0].to_uhwi (),
+ func, ref.sizrange[0].to_uhwi (),
ref.sizrange[1].to_uhwi (),
maxobjsize.to_uhwi ());
return warned ? opt : no_warning;
@@ -1776,9 +1776,9 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
{
auto_diagnostic_group d;
if (warning_at (loc, opt,
- "%G%qD pointer overflow between offset %s "
+ "%qD pointer overflow between offset %s "
"and size %s accessing array %qD with type %qT",
- call, func, rangestr[0], rangestr[1], ref.base, type))
+ func, rangestr[0], rangestr[1], ref.base, type))
{
inform (DECL_SOURCE_LOCATION (ref.base),
"array %qD declared here", ref.base);
@@ -1786,15 +1786,15 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
}
else
warned = warning_at (loc, opt,
- "%G%qD pointer overflow between offset %s "
+ "%qD pointer overflow between offset %s "
"and size %s",
- call, func, rangestr[0], rangestr[1]);
+ func, rangestr[0], rangestr[1]);
}
else
warned = warning_at (loc, opt,
- "%G%qD pointer overflow between offset %s "
+ "%qD pointer overflow between offset %s "
"and size %s",
- call, func, rangestr[0], rangestr[1]);
+ func, rangestr[0], rangestr[1]);
}
else if (oobref == ref.base)
{
@@ -1809,20 +1809,20 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
if ((ref.basesize < maxobjsize
&& warning_at (loc, opt,
form
- ? G_("%G%qD forming offset %s is out of "
+ ? G_("%qD forming offset %s is out of "
"the bounds [0, %wu] of object %qD with "
"type %qT")
- : G_("%G%qD offset %s is out of the bounds "
+ : G_("%qD offset %s is out of the bounds "
"[0, %wu] of object %qD with type %qT"),
- call, func, rangestr[0], ref.basesize.to_uhwi (),
+ func, rangestr[0], ref.basesize.to_uhwi (),
ref.base, TREE_TYPE (ref.base)))
|| warning_at (loc, opt,
form
- ? G_("%G%qD forming offset %s is out of "
+ ? G_("%qD forming offset %s is out of "
"the bounds of object %qD with type %qT")
- : G_("%G%qD offset %s is out of the bounds "
+ : G_("%qD offset %s is out of the bounds "
"of object %qD with type %qT"),
- call, func, rangestr[0],
+ func, rangestr[0],
ref.base, TREE_TYPE (ref.base)))
{
inform (DECL_SOURCE_LOCATION (ref.base),
@@ -1833,17 +1833,17 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
else if (ref.basesize < maxobjsize)
warned = warning_at (loc, opt,
form
- ? G_("%G%qD forming offset %s is out "
+ ? G_("%qD forming offset %s is out "
"of the bounds [0, %wu]")
- : G_("%G%qD offset %s is out "
+ : G_("%qD offset %s is out "
"of the bounds [0, %wu]"),
- call, func, rangestr[0], ref.basesize.to_uhwi ());
+ func, rangestr[0], ref.basesize.to_uhwi ());
else
warned = warning_at (loc, opt,
form
- ? G_("%G%qD forming offset %s is out of bounds")
- : G_("%G%qD offset %s is out of bounds"),
- call, func, rangestr[0]);
+ ? G_("%qD forming offset %s is out of bounds")
+ : G_("%qD offset %s is out of bounds"),
+ func, rangestr[0]);
}
else if (TREE_CODE (ref.ref) == MEM_REF)
{
@@ -1854,9 +1854,9 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
type = TYPE_MAIN_VARIANT (type);
if (warning_at (loc, opt,
- "%G%qD offset %s from the object at %qE is out "
+ "%qD offset %s from the object at %qE is out "
"of the bounds of %qT",
- call, func, rangestr[0], ref.base, type))
+ func, rangestr[0], ref.base, type))
{
if (TREE_CODE (ref.ref) == COMPONENT_REF)
refop = TREE_OPERAND (ref.ref, 1);
@@ -1872,10 +1872,10 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
if (warning_at (loc, opt,
- "%G%qD offset %s from the object at %qE is out "
+ "%qD offset %s from the object at %qE is out "
"of the bounds of referenced subobject %qD with "
"type %qT at offset %wi",
- call, func, rangestr[0], ref.base,
+ func, rangestr[0], ref.base,
TREE_OPERAND (ref.ref, 1), type,
ref.refoff.to_shwi ()))
{
@@ -2065,7 +2065,7 @@ check_bounds_or_overlap (range_query *query,
}
}
- location_t loc = gimple_or_expr_nonartificial_location (call, dst);
+ location_t loc = gimple_location (call);
if (operand_equal_p (dst, src, 0))
{
/* Issue -Wrestrict unless the pointers are null (those do
@@ -2075,8 +2075,8 @@ check_bounds_or_overlap (range_query *query,
if (!integer_zerop (dst) && !warning_suppressed_p (call, OPT_Wrestrict))
{
warning_at (loc, OPT_Wrestrict,
- "%G%qD source argument is the same as destination",
- call, func);
+ "%qD source argument is the same as destination",
+ func);
suppress_warning (call, OPT_Wrestrict);
return OPT_Wrestrict;
}
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ab1384d..4d0f44f 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-01cb2b5e69a2d08ef3cc1ea023c22ed9b79f5114
+adcf10890833026437a94da54934ce50c0018309
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/input.c b/gcc/input.c
index 9e39e7d..de20d98 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -32,9 +32,29 @@ along with GCC; see the file COPYING3. If not see
/* This is a cache used by get_next_line to store the content of a
file to be searched for file lines. */
-class fcache
+class file_cache_slot
{
public:
+ file_cache_slot ();
+ ~file_cache_slot ();
+
+ bool read_line_num (size_t line_num,
+ char ** line, ssize_t *line_len);
+
+ /* Accessors. */
+ const char *get_file_path () const { return m_file_path; }
+ unsigned get_use_count () const { return m_use_count; }
+ bool missing_trailing_newline_p () const
+ {
+ return m_missing_trailing_newline;
+ }
+
+ void inc_use_count () { m_use_count++; }
+
+ void create (const char *file_path, FILE *fp, unsigned highest_use_count);
+ void evict ();
+
+ private:
/* These are information used to store a line boundary. */
class line_info
{
@@ -61,36 +81,48 @@ public:
{}
};
+ bool needs_read_p () const;
+ bool needs_grow_p () const;
+ void maybe_grow ();
+ bool read_data ();
+ bool maybe_read_data ();
+ bool get_next_line (char **line, ssize_t *line_len);
+ bool read_next_line (char ** line, ssize_t *line_len);
+ bool goto_next_line ();
+
+ static const size_t buffer_size = 4 * 1024;
+ static const size_t line_record_size = 100;
+
/* The number of time this file has been accessed. This is used
to designate which file cache to evict from the cache
array. */
- unsigned use_count;
+ unsigned m_use_count;
/* The file_path is the key for identifying a particular file in
the cache.
For libcpp-using code, the underlying buffer for this field is
owned by the corresponding _cpp_file within the cpp_reader. */
- const char *file_path;
+ const char *m_file_path;
- FILE *fp;
+ FILE *m_fp;
/* This points to the content of the file that we've read so
far. */
- char *data;
+ char *m_data;
/* The size of the DATA array above.*/
- size_t size;
+ size_t m_size;
/* The number of bytes read from the underlying file so far. This
must be less (or equal) than SIZE above. */
- size_t nb_read;
+ size_t m_nb_read;
/* The index of the beginning of the current line. */
- size_t line_start_idx;
+ size_t m_line_start_idx;
/* The number of the previous line read. This starts at 1. Zero
means we've read no line so far. */
- size_t line_num;
+ size_t m_line_num;
/* This is the total number of lines of the current file. At the
moment, we try to get this information from the line map
@@ -100,24 +132,21 @@ public:
the number of lines before compilation really starts. For e.g,
the C front-end, it can happen that we start emitting diagnostics
before the line map has seen the end of the file. */
- size_t total_lines;
+ size_t m_total_lines;
/* Could this file be missing a trailing newline on its final line?
Initially true (to cope with empty files), set to true/false
as each line is read. */
- bool missing_trailing_newline;
+ bool m_missing_trailing_newline;
/* This is a record of the beginning and end of the lines we've seen
while reading the file. This is useful to avoid walking the data
from the beginning when we are asked to read a line that is
before LINE_START_IDX above. Note that the maximum size of this
- record is fcache_line_record_size, so that the memory consumption
+ record is line_record_size, so that the memory consumption
doesn't explode. We thus scale total_lines down to
- fcache_line_record_size. */
- vec<line_info, va_heap> line_record;
-
- fcache ();
- ~fcache ();
+ line_record_size. */
+ vec<line_info, va_heap> m_line_record;
};
/* Current position in real source file. */
@@ -133,11 +162,6 @@ class line_maps *line_table;
class line_maps *saved_line_table;
-static fcache *fcache_tab;
-static const size_t fcache_tab_size = 16;
-static const size_t fcache_buffer_size = 4 * 1024;
-static const size_t fcache_line_record_size = 100;
-
/* Expand the source location LOC into a human readable location. If
LOC resolves to a builtin location, the file name of the readable
location is set to the string "<built-in>". If EXPANSION_POINT_P is
@@ -233,8 +257,9 @@ expand_location_1 (location_t loc,
static void
diagnostic_file_cache_init (void)
{
- if (fcache_tab == NULL)
- fcache_tab = new fcache[fcache_tab_size];
+ gcc_assert (global_dc);
+ if (global_dc->m_file_cache == NULL)
+ global_dc->m_file_cache = new file_cache ();
}
/* Free the resources used by the set of cache used for files accessed
@@ -243,10 +268,10 @@ diagnostic_file_cache_init (void)
void
diagnostic_file_cache_fini (void)
{
- if (fcache_tab)
+ if (global_dc->m_file_cache)
{
- delete [] (fcache_tab);
- fcache_tab = NULL;
+ delete global_dc->m_file_cache;
+ global_dc->m_file_cache = NULL;
}
}
@@ -273,28 +298,25 @@ total_lines_num (const char *file_path)
caret diagnostic. Return the found cached file, or NULL if no
cached file was found. */
-static fcache*
-lookup_file_in_cache_tab (const char *file_path)
+file_cache_slot *
+file_cache::lookup_file (const char *file_path)
{
- if (file_path == NULL)
- return NULL;
-
- diagnostic_file_cache_init ();
+ gcc_assert (file_path);
/* This will contain the found cached file. */
- fcache *r = NULL;
- for (unsigned i = 0; i < fcache_tab_size; ++i)
+ file_cache_slot *r = NULL;
+ for (unsigned i = 0; i < num_file_slots; ++i)
{
- fcache *c = &fcache_tab[i];
- if (c->file_path && !strcmp (c->file_path, file_path))
+ file_cache_slot *c = &m_file_slots[i];
+ if (c->get_file_path () && !strcmp (c->get_file_path (), file_path))
{
- ++c->use_count;
+ c->inc_use_count ();
r = c;
}
}
if (r)
- ++r->use_count;
+ r->inc_use_count ();
return r;
}
@@ -308,22 +330,39 @@ diagnostics_file_cache_forcibly_evict_file (const char *file_path)
{
gcc_assert (file_path);
- fcache *r = lookup_file_in_cache_tab (file_path);
+ if (!global_dc->m_file_cache)
+ return;
+
+ global_dc->m_file_cache->forcibly_evict_file (file_path);
+}
+
+void
+file_cache::forcibly_evict_file (const char *file_path)
+{
+ gcc_assert (file_path);
+
+ file_cache_slot *r = lookup_file (file_path);
if (!r)
/* Not found. */
return;
- r->file_path = NULL;
- if (r->fp)
- fclose (r->fp);
- r->fp = NULL;
- r->nb_read = 0;
- r->line_start_idx = 0;
- r->line_num = 0;
- r->line_record.truncate (0);
- r->use_count = 0;
- r->total_lines = 0;
- r->missing_trailing_newline = true;
+ r->evict ();
+}
+
+void
+file_cache_slot::evict ()
+{
+ m_file_path = NULL;
+ if (m_fp)
+ fclose (m_fp);
+ m_fp = NULL;
+ m_nb_read = 0;
+ m_line_start_idx = 0;
+ m_line_num = 0;
+ m_line_record.truncate (0);
+ m_use_count = 0;
+ m_total_lines = 0;
+ m_missing_trailing_newline = true;
}
/* Return the file cache that has been less used, recently, or the
@@ -331,26 +370,26 @@ diagnostics_file_cache_forcibly_evict_file (const char *file_path)
*HIGHEST_USE_COUNT is set to the highest use count of the entries
in the cache table. */
-static fcache*
-evicted_cache_tab_entry (unsigned *highest_use_count)
+file_cache_slot*
+file_cache::evicted_cache_tab_entry (unsigned *highest_use_count)
{
diagnostic_file_cache_init ();
- fcache *to_evict = &fcache_tab[0];
- unsigned huc = to_evict->use_count;
- for (unsigned i = 1; i < fcache_tab_size; ++i)
+ file_cache_slot *to_evict = &m_file_slots[0];
+ unsigned huc = to_evict->get_use_count ();
+ for (unsigned i = 1; i < num_file_slots; ++i)
{
- fcache *c = &fcache_tab[i];
- bool c_is_empty = (c->file_path == NULL);
+ file_cache_slot *c = &m_file_slots[i];
+ bool c_is_empty = (c->get_file_path () == NULL);
- if (c->use_count < to_evict->use_count
- || (to_evict->file_path && c_is_empty))
+ if (c->get_use_count () < to_evict->get_use_count ()
+ || (to_evict->get_file_path () && c_is_empty))
/* We evict C because it's either an entry with a lower use
count or one that is empty. */
to_evict = c;
- if (huc < c->use_count)
- huc = c->use_count;
+ if (huc < c->get_use_count ())
+ huc = c->get_use_count ();
if (c_is_empty)
/* We've reached the end of the cache; subsequent elements are
@@ -368,10 +407,10 @@ evicted_cache_tab_entry (unsigned *highest_use_count)
accessed by caret diagnostic. This cache is added to an array of
cache and can be retrieved by lookup_file_in_cache_tab. This
function returns the created cache. Note that only the last
- fcache_tab_size files are cached. */
+ num_file_slots files are cached. */
-static fcache*
-add_file_to_cache_tab (const char *file_path)
+file_cache_slot*
+file_cache::add_file (const char *file_path)
{
FILE *fp = fopen (file_path, "r");
@@ -379,22 +418,45 @@ add_file_to_cache_tab (const char *file_path)
return NULL;
unsigned highest_use_count = 0;
- fcache *r = evicted_cache_tab_entry (&highest_use_count);
- r->file_path = file_path;
- if (r->fp)
- fclose (r->fp);
- r->fp = fp;
- r->nb_read = 0;
- r->line_start_idx = 0;
- r->line_num = 0;
- r->line_record.truncate (0);
+ file_cache_slot *r = evicted_cache_tab_entry (&highest_use_count);
+ r->create (file_path, fp, highest_use_count);
+ return r;
+}
+
+/* Populate this slot for use on FILE_PATH and FP, dropping any
+ existing cached content within it. */
+
+void
+file_cache_slot::create (const char *file_path, FILE *fp,
+ unsigned highest_use_count)
+{
+ m_file_path = file_path;
+ if (m_fp)
+ fclose (m_fp);
+ m_fp = fp;
+ m_nb_read = 0;
+ m_line_start_idx = 0;
+ m_line_num = 0;
+ m_line_record.truncate (0);
/* Ensure that this cache entry doesn't get evicted next time
add_file_to_cache_tab is called. */
- r->use_count = ++highest_use_count;
- r->total_lines = total_lines_num (file_path);
- r->missing_trailing_newline = true;
+ m_use_count = ++highest_use_count;
+ m_total_lines = total_lines_num (file_path);
+ m_missing_trailing_newline = true;
+}
- return r;
+/* file_cache's ctor. */
+
+file_cache::file_cache ()
+: m_file_slots (new file_cache_slot[num_file_slots])
+{
+}
+
+/* file_cache's dtor. */
+
+file_cache::~file_cache ()
+{
+ delete[] m_file_slots;
}
/* Lookup the cache used for the content of a given file accessed by
@@ -402,41 +464,41 @@ add_file_to_cache_tab (const char *file_path)
for this file, add it to the array of cached file and return
it. */
-static fcache*
-lookup_or_add_file_to_cache_tab (const char *file_path)
+file_cache_slot*
+file_cache::lookup_or_add_file (const char *file_path)
{
- fcache *r = lookup_file_in_cache_tab (file_path);
+ file_cache_slot *r = lookup_file (file_path);
if (r == NULL)
- r = add_file_to_cache_tab (file_path);
+ r = add_file (file_path);
return r;
}
/* Default constructor for a cache of file used by caret
diagnostic. */
-fcache::fcache ()
-: use_count (0), file_path (NULL), fp (NULL), data (0),
- size (0), nb_read (0), line_start_idx (0), line_num (0),
- total_lines (0), missing_trailing_newline (true)
+file_cache_slot::file_cache_slot ()
+: m_use_count (0), m_file_path (NULL), m_fp (NULL), m_data (0),
+ m_size (0), m_nb_read (0), m_line_start_idx (0), m_line_num (0),
+ m_total_lines (0), m_missing_trailing_newline (true)
{
- line_record.create (0);
+ m_line_record.create (0);
}
/* Destructor for a cache of file used by caret diagnostic. */
-fcache::~fcache ()
+file_cache_slot::~file_cache_slot ()
{
- if (fp)
+ if (m_fp)
{
- fclose (fp);
- fp = NULL;
+ fclose (m_fp);
+ m_fp = NULL;
}
- if (data)
+ if (m_data)
{
- XDELETEVEC (data);
- data = 0;
+ XDELETEVEC (m_data);
+ m_data = 0;
}
- line_record.release ();
+ m_line_record.release ();
}
/* Returns TRUE iff the cache would need to be filled with data coming
@@ -444,55 +506,55 @@ fcache::~fcache ()
current line is empty. Note that if the cache is full, it would
need to be extended and filled again. */
-static bool
-needs_read (fcache *c)
+bool
+file_cache_slot::needs_read_p () const
{
- return (c->nb_read == 0
- || c->nb_read == c->size
- || (c->line_start_idx >= c->nb_read - 1));
+ return (m_nb_read == 0
+ || m_nb_read == m_size
+ || (m_line_start_idx >= m_nb_read - 1));
}
/* Return TRUE iff the cache is full and thus needs to be
extended. */
-static bool
-needs_grow (fcache *c)
+bool
+file_cache_slot::needs_grow_p () const
{
- return c->nb_read == c->size;
+ return m_nb_read == m_size;
}
/* Grow the cache if it needs to be extended. */
-static void
-maybe_grow (fcache *c)
+void
+file_cache_slot::maybe_grow ()
{
- if (!needs_grow (c))
+ if (!needs_grow_p ())
return;
- size_t size = c->size == 0 ? fcache_buffer_size : c->size * 2;
- c->data = XRESIZEVEC (char, c->data, size);
- c->size = size;
+ size_t size = m_size == 0 ? buffer_size : m_size * 2;
+ m_data = XRESIZEVEC (char, m_data, size);
+ m_size = size;
}
/* Read more data into the cache. Extends the cache if need be.
Returns TRUE iff new data could be read. */
-static bool
-read_data (fcache *c)
+bool
+file_cache_slot::read_data ()
{
- if (feof (c->fp) || ferror (c->fp))
+ if (feof (m_fp) || ferror (m_fp))
return false;
- maybe_grow (c);
+ maybe_grow ();
- char * from = c->data + c->nb_read;
- size_t to_read = c->size - c->nb_read;
- size_t nb_read = fread (from, 1, to_read, c->fp);
+ char * from = m_data + m_nb_read;
+ size_t to_read = m_size - m_nb_read;
+ size_t nb_read = fread (from, 1, to_read, m_fp);
- if (ferror (c->fp))
+ if (ferror (m_fp))
return false;
- c->nb_read += nb_read;
+ m_nb_read += nb_read;
return !!nb_read;
}
@@ -500,12 +562,12 @@ read_data (fcache *c)
coming from the file FP. Return TRUE iff the cache was filled with
mode data. */
-static bool
-maybe_read_data (fcache *c)
+bool
+file_cache_slot::maybe_read_data ()
{
- if (!needs_read (c))
+ if (!needs_read_p ())
return false;
- return read_data (c);
+ return read_data ();
}
/* Read a new line from file FP, using C as a cache for the data
@@ -518,18 +580,18 @@ maybe_read_data (fcache *c)
otherwise. Note that subsequent calls to get_next_line might
make the content of *LINE invalid. */
-static bool
-get_next_line (fcache *c, char **line, ssize_t *line_len)
+bool
+file_cache_slot::get_next_line (char **line, ssize_t *line_len)
{
/* Fill the cache with data to process. */
- maybe_read_data (c);
+ maybe_read_data ();
- size_t remaining_size = c->nb_read - c->line_start_idx;
+ size_t remaining_size = m_nb_read - m_line_start_idx;
if (remaining_size == 0)
/* There is no more data to process. */
return false;
- char *line_start = c->data + c->line_start_idx;
+ char *line_start = m_data + m_line_start_idx;
char *next_line_start = NULL;
size_t len = 0;
@@ -539,10 +601,10 @@ get_next_line (fcache *c, char **line, ssize_t *line_len)
/* We haven't found the end-of-line delimiter in the cache.
Fill the cache with more data from the file and look for the
'\n'. */
- while (maybe_read_data (c))
+ while (maybe_read_data ())
{
- line_start = c->data + c->line_start_idx;
- remaining_size = c->nb_read - c->line_start_idx;
+ line_start = m_data + m_line_start_idx;
+ remaining_size = m_nb_read - m_line_start_idx;
line_end = (char *) memchr (line_start, '\n', remaining_size);
if (line_end != NULL)
{
@@ -558,19 +620,19 @@ get_next_line (fcache *c, char **line, ssize_t *line_len)
of when the line ends up with a '\n' and line_end points to
that terminal '\n'. That consistency is useful below in
the len calculation. */
- line_end = c->data + c->nb_read ;
- c->missing_trailing_newline = true;
+ line_end = m_data + m_nb_read ;
+ m_missing_trailing_newline = true;
}
else
- c->missing_trailing_newline = false;
+ m_missing_trailing_newline = false;
}
else
{
next_line_start = line_end + 1;
- c->missing_trailing_newline = false;
+ m_missing_trailing_newline = false;
}
- if (ferror (c->fp))
+ if (ferror (m_fp))
return false;
/* At this point, we've found the end of the of line. It either
@@ -580,54 +642,56 @@ get_next_line (fcache *c, char **line, ssize_t *line_len)
len = line_end - line_start;
- if (c->line_start_idx < c->nb_read)
+ if (m_line_start_idx < m_nb_read)
*line = line_start;
- ++c->line_num;
+ ++m_line_num;
/* Before we update our line record, make sure the hint about the
total number of lines of the file is correct. If it's not, then
we give up recording line boundaries from now on. */
bool update_line_record = true;
- if (c->line_num > c->total_lines)
+ if (m_line_num > m_total_lines)
update_line_record = false;
/* Now update our line record so that re-reading lines from the
- before c->line_start_idx is faster. */
+ before m_line_start_idx is faster. */
if (update_line_record
- && c->line_record.length () < fcache_line_record_size)
+ && m_line_record.length () < line_record_size)
{
/* If the file lines fits in the line record, we just record all
its lines ...*/
- if (c->total_lines <= fcache_line_record_size
- && c->line_num > c->line_record.length ())
- c->line_record.safe_push (fcache::line_info (c->line_num,
- c->line_start_idx,
- line_end - c->data));
- else if (c->total_lines > fcache_line_record_size)
+ if (m_total_lines <= line_record_size
+ && m_line_num > m_line_record.length ())
+ m_line_record.safe_push
+ (file_cache_slot::line_info (m_line_num,
+ m_line_start_idx,
+ line_end - m_data));
+ else if (m_total_lines > line_record_size)
{
/* ... otherwise, we just scale total_lines down to
- (fcache_line_record_size lines. */
- size_t n = (c->line_num * fcache_line_record_size) / c->total_lines;
- if (c->line_record.length () == 0
- || n >= c->line_record.length ())
- c->line_record.safe_push (fcache::line_info (c->line_num,
- c->line_start_idx,
- line_end - c->data));
+ (line_record_size lines. */
+ size_t n = (m_line_num * line_record_size) / m_total_lines;
+ if (m_line_record.length () == 0
+ || n >= m_line_record.length ())
+ m_line_record.safe_push
+ (file_cache_slot::line_info (m_line_num,
+ m_line_start_idx,
+ line_end - m_data));
}
}
- /* Update c->line_start_idx so that it points to the next line to be
+ /* Update m_line_start_idx so that it points to the next line to be
read. */
if (next_line_start)
- c->line_start_idx = next_line_start - c->data;
+ m_line_start_idx = next_line_start - m_data;
else
/* We didn't find any terminal '\n'. Let's consider that the end
of line is the end of the data in the cache. The next
invocation of get_next_line will either read more data from the
underlying file or return false early because we've reached the
end of the file. */
- c->line_start_idx = c->nb_read;
+ m_line_start_idx = m_nb_read;
*line_len = len;
@@ -640,13 +704,13 @@ get_next_line (fcache *c, char **line, ssize_t *line_len)
copying from the cache involved. Return TRUE upon successful
completion. */
-static bool
-goto_next_line (fcache *cache)
+bool
+file_cache_slot::goto_next_line ()
{
char *l;
ssize_t len;
- return get_next_line (cache, &l, &len);
+ return get_next_line (&l, &len);
}
/* Read an arbitrary line number LINE_NUM from the file cached in C.
@@ -656,54 +720,54 @@ goto_next_line (fcache *cache)
*LINE is only valid until the next call of read_line_num.
This function returns bool if a line was read. */
-static bool
-read_line_num (fcache *c, size_t line_num,
- char **line, ssize_t *line_len)
+bool
+file_cache_slot::read_line_num (size_t line_num,
+ char ** line, ssize_t *line_len)
{
gcc_assert (line_num > 0);
- if (line_num <= c->line_num)
+ if (line_num <= m_line_num)
{
- /* We've been asked to read lines that are before c->line_num.
+ /* We've been asked to read lines that are before m_line_num.
So lets use our line record (if it's not empty) to try to
avoid re-reading the file from the beginning again. */
- if (c->line_record.is_empty ())
+ if (m_line_record.is_empty ())
{
- c->line_start_idx = 0;
- c->line_num = 0;
+ m_line_start_idx = 0;
+ m_line_num = 0;
}
else
{
- fcache::line_info *i = NULL;
- if (c->total_lines <= fcache_line_record_size)
+ file_cache_slot::line_info *i = NULL;
+ if (m_total_lines <= line_record_size)
{
/* In languages where the input file is not totally
- preprocessed up front, the c->total_lines hint
+ preprocessed up front, the m_total_lines hint
can be smaller than the number of lines of the
file. In that case, only the first
- c->total_lines have been recorded.
+ m_total_lines have been recorded.
- Otherwise, the first c->total_lines we've read have
+ Otherwise, the first m_total_lines we've read have
their start/end recorded here. */
- i = (line_num <= c->total_lines)
- ? &c->line_record[line_num - 1]
- : &c->line_record[c->total_lines - 1];
+ i = (line_num <= m_total_lines)
+ ? &m_line_record[line_num - 1]
+ : &m_line_record[m_total_lines - 1];
gcc_assert (i->line_num <= line_num);
}
else
{
/* So the file had more lines than our line record
size. Thus the number of lines we've recorded has
- been scaled down to fcache_line_reacord_size. Let's
+ been scaled down to line_record_size. Let's
pick the start/end of the recorded line that is
closest to line_num. */
- size_t n = (line_num <= c->total_lines)
- ? line_num * fcache_line_record_size / c->total_lines
- : c ->line_record.length () - 1;
- if (n < c->line_record.length ())
+ size_t n = (line_num <= m_total_lines)
+ ? line_num * line_record_size / m_total_lines
+ : m_line_record.length () - 1;
+ if (n < m_line_record.length ())
{
- i = &c->line_record[n];
+ i = &m_line_record[n];
gcc_assert (i->line_num <= line_num);
}
}
@@ -711,33 +775,33 @@ read_line_num (fcache *c, size_t line_num,
if (i && i->line_num == line_num)
{
/* We have the start/end of the line. */
- *line = c->data + i->start_pos;
+ *line = m_data + i->start_pos;
*line_len = i->end_pos - i->start_pos;
return true;
}
if (i)
{
- c->line_start_idx = i->start_pos;
- c->line_num = i->line_num - 1;
+ m_line_start_idx = i->start_pos;
+ m_line_num = i->line_num - 1;
}
else
{
- c->line_start_idx = 0;
- c->line_num = 0;
+ m_line_start_idx = 0;
+ m_line_num = 0;
}
}
}
- /* Let's walk from line c->line_num up to line_num - 1, without
+ /* Let's walk from line m_line_num up to line_num - 1, without
copying any line. */
- while (c->line_num < line_num - 1)
- if (!goto_next_line (c))
+ while (m_line_num < line_num - 1)
+ if (!goto_next_line ())
return false;
/* The line we want is the next one. Let's read and copy it back to
the caller. */
- return get_next_line (c, line, line_len);
+ return get_next_line (line, line_len);
}
/* Return the physical source line that corresponds to FILE_PATH/LINE.
@@ -756,11 +820,16 @@ location_get_source_line (const char *file_path, int line)
if (line == 0)
return char_span (NULL, 0);
- fcache *c = lookup_or_add_file_to_cache_tab (file_path);
+ if (file_path == NULL)
+ return char_span (NULL, 0);
+
+ diagnostic_file_cache_init ();
+
+ file_cache_slot *c = global_dc->m_file_cache->lookup_or_add_file (file_path);
if (c == NULL)
return char_span (NULL, 0);
- bool read = read_line_num (c, line, &buffer, &len);
+ bool read = c->read_line_num (line, &buffer, &len);
if (!read)
return char_span (NULL, 0);
@@ -774,11 +843,13 @@ location_get_source_line (const char *file_path, int line)
bool
location_missing_trailing_newline (const char *file_path)
{
- fcache *c = lookup_or_add_file_to_cache_tab (file_path);
+ diagnostic_file_cache_init ();
+
+ file_cache_slot *c = global_dc->m_file_cache->lookup_or_add_file (file_path);
if (c == NULL)
return false;
- return c->missing_trailing_newline;
+ return c->missing_trailing_newline_p ();
}
/* Test if the location originates from the spelling location of a
diff --git a/gcc/input.h b/gcc/input.h
index f1ef5d7..bbcec84 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -88,6 +88,39 @@ class char_span
extern char_span location_get_source_line (const char *file_path, int line);
extern bool location_missing_trailing_newline (const char *file_path);
+
+/* Forward decl of slot within file_cache, so that the definition doesn't
+ need to be in this header. */
+class file_cache_slot;
+
+/* A cache of source files for use when emitting diagnostics
+ (and in a few places in the C/C++ frontends).
+
+ Results are only valid until the next call to the cache, as
+ slots can be evicted.
+
+ Filenames are stored by pointer, and so must outlive the cache
+ instance. */
+
+class file_cache
+{
+ public:
+ file_cache ();
+ ~file_cache ();
+
+ file_cache_slot *lookup_or_add_file (const char *file_path);
+ void forcibly_evict_file (const char *file_path);
+
+ private:
+ file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count);
+ file_cache_slot *add_file (const char *file_path);
+ file_cache_slot *lookup_file (const char *file_path);
+
+ private:
+ static const size_t num_file_slots = 16;
+ file_cache_slot *m_file_slots;
+};
+
extern expanded_location
expand_location_to_spelling_point (location_t,
enum location_aspect aspect
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index c3b8e73..a7003d5 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -282,7 +282,8 @@ DEF_INTERNAL_OPTAB_FN (COMPLEX_ADD_ROT270, ECF_CONST, cadd270, binary)
DEF_INTERNAL_OPTAB_FN (COMPLEX_MUL, ECF_CONST, cmul, binary)
DEF_INTERNAL_OPTAB_FN (COMPLEX_MUL_CONJ, ECF_CONST, cmul_conj, binary)
DEF_INTERNAL_OPTAB_FN (VEC_ADDSUB, ECF_CONST, vec_addsub, binary)
-
+DEF_INTERNAL_OPTAB_FN (VEC_FMADDSUB, ECF_CONST, vec_fmaddsub, ternary)
+DEF_INTERNAL_OPTAB_FN (VEC_FMSUBADD, ECF_CONST, vec_fmsubadd, ternary)
/* FP scales. */
DEF_INTERNAL_FLT_FN (LDEXP, ECF_CONST, ldexp, binary)
diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index 3272daf..965e246 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -343,7 +343,7 @@ class isra_call_summary
public:
isra_call_summary ()
: m_arg_flow (), m_return_ignored (false), m_return_returned (false),
- m_bit_aligned_arg (false)
+ m_bit_aligned_arg (false), m_before_any_store (false)
{}
void init_inputs (unsigned arg_count);
@@ -362,6 +362,10 @@ public:
/* Set when any of the call arguments are not byte-aligned. */
unsigned m_bit_aligned_arg : 1;
+
+ /* Set to true if the call happend before any (other) store to memory in the
+ caller. */
+ unsigned m_before_any_store : 1;
};
/* Class to manage function summaries. */
@@ -491,6 +495,8 @@ isra_call_summary::dump (FILE *f)
fprintf (f, " return value ignored\n");
if (m_return_returned)
fprintf (f, " return value used only to compute caller return value\n");
+ if (m_before_any_store)
+ fprintf (f, " happens before any store to memory\n");
for (unsigned i = 0; i < m_arg_flow.length (); i++)
{
fprintf (f, " Parameter %u:\n", i);
@@ -535,6 +541,7 @@ ipa_sra_call_summaries::duplicate (cgraph_edge *, cgraph_edge *,
new_sum->m_return_ignored = old_sum->m_return_ignored;
new_sum->m_return_returned = old_sum->m_return_returned;
new_sum->m_bit_aligned_arg = old_sum->m_bit_aligned_arg;
+ new_sum->m_before_any_store = old_sum->m_before_any_store;
}
@@ -2374,6 +2381,7 @@ process_scan_results (cgraph_node *node, struct function *fun,
unsigned count = gimple_call_num_args (call_stmt);
isra_call_summary *csum = call_sums->get_create (cs);
csum->init_inputs (count);
+ csum->m_before_any_store = uses_memory_as_obtained;
for (unsigned argidx = 0; argidx < count; argidx++)
{
if (!csum->m_arg_flow[argidx].pointer_pass_through)
@@ -2546,6 +2554,7 @@ isra_write_edge_summary (output_block *ob, cgraph_edge *e)
bp_pack_value (&bp, csum->m_return_ignored, 1);
bp_pack_value (&bp, csum->m_return_returned, 1);
bp_pack_value (&bp, csum->m_bit_aligned_arg, 1);
+ bp_pack_value (&bp, csum->m_before_any_store, 1);
streamer_write_bitpack (&bp);
}
@@ -2664,6 +2673,7 @@ isra_read_edge_summary (struct lto_input_block *ib, cgraph_edge *cs)
csum->m_return_ignored = bp_unpack_value (&bp, 1);
csum->m_return_returned = bp_unpack_value (&bp, 1);
csum->m_bit_aligned_arg = bp_unpack_value (&bp, 1);
+ csum->m_before_any_store = bp_unpack_value (&bp, 1);
}
/* Read intraprocedural analysis information about NODE and all of its outgoing
@@ -3420,7 +3430,8 @@ param_splitting_across_edge (cgraph_edge *cs)
}
else if (!ipf->safe_to_import_accesses)
{
- if (!all_callee_accesses_present_p (param_desc, arg_desc))
+ if (!csum->m_before_any_store
+ || !all_callee_accesses_present_p (param_desc, arg_desc))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " %u->%u: cannot import accesses.\n",
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index d83cfc1..86c6f24 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -233,19 +233,30 @@ go_through_subreg (rtx x, int *offset)
return reg;
}
+/* Return the recomputed frequency for this shuffle copy or its similar
+ case, since it's not for a real move insn, make it smaller. */
+
+static int
+get_freq_for_shuffle_copy (int freq)
+{
+ return freq < 8 ? 1 : freq / 8;
+}
+
/* Process registers REG1 and REG2 in move INSN with execution
frequency FREQ. The function also processes the registers in a
potential move insn (INSN == NULL in this case) with frequency
FREQ. The function can modify hard register costs of the
corresponding allocnos or create a copy involving the corresponding
allocnos. The function does nothing if the both registers are hard
- registers. When nothing is changed, the function returns
- FALSE. */
+ registers. When nothing is changed, the function returns FALSE.
+ SINGLE_INPUT_OP_HAS_CSTR_P is only meaningful when constraint_p
+ is true, see function ira_get_dup_out_num for its meaning. */
static bool
-process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
- rtx_insn *insn, int freq)
+process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, rtx_insn *insn,
+ int freq, bool single_input_op_has_cstr_p = true)
{
- int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
+ int allocno_preferenced_hard_regno, index, offset1, offset2;
+ int cost, conflict_cost, move_cost;
bool only_regs_p;
ira_allocno_t a;
reg_class_t rclass, aclass;
@@ -306,9 +317,52 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
return false;
ira_init_register_move_cost_if_necessary (mode);
if (HARD_REGISTER_P (reg1))
- cost = ira_register_move_cost[mode][aclass][rclass] * freq;
+ move_cost = ira_register_move_cost[mode][aclass][rclass];
+ else
+ move_cost = ira_register_move_cost[mode][rclass][aclass];
+
+ if (!single_input_op_has_cstr_p)
+ {
+ /* When this is a constraint copy and the matching constraint
+ doesn't only exist for this given operand but also for some
+ other operand(s), it means saving the possible move cost does
+ NOT need to require reg1 and reg2 to use the same hardware
+ register, so this hardware preference isn't required to be
+ fixed. To avoid it to over prefer this hardware register,
+ and over disparage this hardware register on conflicted
+ objects, we need some cost tweaking here, similar to what
+ we do for shuffle copy. */
+ gcc_assert (constraint_p);
+ int reduced_freq = get_freq_for_shuffle_copy (freq);
+ if (HARD_REGISTER_P (reg1))
+ /* For reg2 = opcode(reg1, reg3 ...), assume that reg3 is a
+ pseudo register which has matching constraint on reg2,
+ even if reg2 isn't assigned by reg1, it's still possible
+ not to have register moves if reg2 and reg3 use the same
+ hardware register. So to avoid the allocation to over
+ prefer reg1, we can just take it as a shuffle copy. */
+ cost = conflict_cost = move_cost * reduced_freq;
+ else
+ {
+ /* For reg1 = opcode(reg2, reg3 ...), assume that reg3 is a
+ pseudo register which has matching constraint on reg2,
+ to save the register move, it's better to assign reg1
+ to either of reg2 and reg3 (or one of other pseudos like
+ reg3), it's reasonable to use freq for the cost. But
+ for conflict_cost, since reg2 and reg3 conflicts with
+ each other, both of them has the chance to be assigned
+ by reg1, assume reg3 has one copy which also conflicts
+ with reg2, we shouldn't make it less preferred on reg1
+ since reg3 has the same chance to be assigned by reg1.
+ So it adjusts the conflic_cost to make it same as what
+ we use for shuffle copy. */
+ cost = move_cost * freq;
+ conflict_cost = move_cost * reduced_freq;
+ }
+ }
else
- cost = ira_register_move_cost[mode][rclass][aclass] * freq;
+ cost = conflict_cost = move_cost * freq;
+
do
{
ira_allocate_and_set_costs
@@ -317,7 +371,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
ira_allocate_and_set_costs
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
- ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
+ ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= conflict_cost;
if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
@@ -420,7 +474,8 @@ add_insn_allocno_copies (rtx_insn *insn)
operand = recog_data.operand[i];
if (! REG_SUBREG_P (operand))
continue;
- if ((n = ira_get_dup_out_num (i, alts)) >= 0)
+ bool single_input_op_has_cstr_p;
+ if ((n = ira_get_dup_out_num (i, alts, single_input_op_has_cstr_p)) >= 0)
{
bound_p[n] = true;
dup = recog_data.operand[n];
@@ -429,8 +484,8 @@ add_insn_allocno_copies (rtx_insn *insn)
REG_P (operand)
? operand
: SUBREG_REG (operand)) != NULL_RTX)
- process_regs_for_copy (operand, dup, true, NULL,
- freq);
+ process_regs_for_copy (operand, dup, true, NULL, freq,
+ single_input_op_has_cstr_p);
}
}
for (i = 0; i < recog_data.n_operands; i++)
@@ -440,13 +495,15 @@ add_insn_allocno_copies (rtx_insn *insn)
&& find_reg_note (insn, REG_DEAD,
REG_P (operand)
? operand : SUBREG_REG (operand)) != NULL_RTX)
- /* If an operand dies, prefer its hard register for the output
- operands by decreasing the hard register cost or creating
- the corresponding allocno copies. The cost will not
- correspond to a real move insn cost, so make the frequency
- smaller. */
- process_reg_shuffles (insn, operand, i, freq < 8 ? 1 : freq / 8,
- bound_p);
+ {
+ /* If an operand dies, prefer its hard register for the output
+ operands by decreasing the hard register cost or creating
+ the corresponding allocno copies. The cost will not
+ correspond to a real move insn cost, so make the frequency
+ smaller. */
+ int new_freq = get_freq_for_shuffle_copy (freq);
+ process_reg_shuffles (insn, operand, i, new_freq, bound_p);
+ }
}
}
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 31e013b..da74862 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -971,7 +971,7 @@ extern void ira_debug_disposition (void);
extern void ira_debug_allocno_classes (void);
extern void ira_init_register_move_cost (machine_mode);
extern alternative_mask ira_setup_alts (rtx_insn *);
-extern int ira_get_dup_out_num (int, alternative_mask);
+extern int ira_get_dup_out_num (int, alternative_mask, bool &);
/* ira-build.c */
diff --git a/gcc/ira.c b/gcc/ira.c
index 638ef4e..866fb98 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1922,9 +1922,25 @@ ira_setup_alts (rtx_insn *insn)
/* Return the number of the output non-early clobber operand which
should be the same in any case as operand with number OP_NUM (or
negative value if there is no such operand). ALTS is the mask
- of alternatives that we should consider. */
+ of alternatives that we should consider. SINGLE_INPUT_OP_HAS_CSTR_P
+ should be set in this function, it indicates whether there is only
+ a single input operand which has the matching constraint on the
+ output operand at the position specified in return value. If the
+ pattern allows any one of several input operands holds the matching
+ constraint, it's set as false, one typical case is destructive FMA
+ instruction on target rs6000. Note that for a non-NO_REG preferred
+ register class with no free register move copy, if the parameter
+ PARAM_IRA_CONSIDER_DUP_IN_ALL_ALTS is set to one, this function
+ will check all available alternatives for matching constraints,
+ even if it has found or will find one alternative with non-NO_REG
+ regclass, it can respect more cases with matching constraints. If
+ PARAM_IRA_CONSIDER_DUP_IN_ALL_ALTS is set to zero,
+ SINGLE_INPUT_OP_HAS_CSTR_P is always true, it will stop to find
+ matching constraint relationship once it hits some alternative with
+ some non-NO_REG regclass. */
int
-ira_get_dup_out_num (int op_num, alternative_mask alts)
+ira_get_dup_out_num (int op_num, alternative_mask alts,
+ bool &single_input_op_has_cstr_p)
{
int curr_alt, c, original;
bool ignore_p, use_commut_op_p;
@@ -1937,10 +1953,42 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
return -1;
str = recog_data.constraints[op_num];
use_commut_op_p = false;
+ single_input_op_has_cstr_p = true;
+
+ rtx op = recog_data.operand[op_num];
+ int op_regno = reg_or_subregno (op);
+ enum reg_class op_pref_cl = reg_preferred_class (op_regno);
+ machine_mode op_mode = GET_MODE (op);
+
+ ira_init_register_move_cost_if_necessary (op_mode);
+ /* If the preferred regclass isn't NO_REG, continue to find the matching
+ constraint in all available alternatives with preferred regclass, even
+ if we have found or will find one alternative whose constraint stands
+ for a REG (non-NO_REG) regclass. Note that it would be fine not to
+ respect matching constraint if the register copy is free, so exclude
+ it. */
+ bool respect_dup_despite_reg_cstr
+ = param_ira_consider_dup_in_all_alts
+ && op_pref_cl != NO_REGS
+ && ira_register_move_cost[op_mode][op_pref_cl][op_pref_cl] > 0;
+
+ /* Record the alternative whose constraint uses the same regclass as the
+ preferred regclass, later if we find one matching constraint for this
+ operand with preferred reclass, we will visit these recorded
+ alternatives to check whether if there is one alternative in which no
+ any INPUT operands have one matching constraint same as our candidate.
+ If yes, it means there is one alternative which is perfectly fine
+ without satisfying this matching constraint. If no, it means in any
+ alternatives there is one other INPUT operand holding this matching
+ constraint, it's fine to respect this matching constraint and further
+ create this constraint copy since it would become harmless once some
+ other takes preference and it's interfered. */
+ alternative_mask pref_cl_alts;
+
for (;;)
{
- rtx op = recog_data.operand[op_num];
-
+ pref_cl_alts = 0;
+
for (curr_alt = 0, ignore_p = !TEST_BIT (alts, curr_alt),
original = -1;;)
{
@@ -1963,9 +2011,25 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
{
enum constraint_num cn = lookup_constraint (str);
enum reg_class cl = reg_class_for_constraint (cn);
- if (cl != NO_REGS
- && !targetm.class_likely_spilled_p (cl))
- goto fail;
+ if (cl != NO_REGS && !targetm.class_likely_spilled_p (cl))
+ {
+ if (respect_dup_despite_reg_cstr)
+ {
+ /* If it's free to move from one preferred class to
+ the one without matching constraint, it doesn't
+ have to respect this constraint with costs. */
+ if (cl != op_pref_cl
+ && (ira_reg_class_intersect[cl][op_pref_cl]
+ != NO_REGS)
+ && (ira_may_move_in_cost[op_mode][op_pref_cl][cl]
+ == 0))
+ goto fail;
+ else if (cl == op_pref_cl)
+ pref_cl_alts |= ALTERNATIVE_BIT (curr_alt);
+ }
+ else
+ goto fail;
+ }
if (constraint_satisfied_p (op, cn))
goto fail;
break;
@@ -1979,7 +2043,21 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
str = end;
if (original != -1 && original != n)
goto fail;
- original = n;
+ gcc_assert (n < recog_data.n_operands);
+ if (respect_dup_despite_reg_cstr)
+ {
+ const operand_alternative *op_alt
+ = &recog_op_alt[curr_alt * recog_data.n_operands];
+ /* Only respect the one with preferred rclass, without
+ respect_dup_despite_reg_cstr it's possible to get
+ one whose regclass isn't preferred first before,
+ but it would fail since there should be other
+ alternatives with preferred regclass. */
+ if (op_alt[n].cl == op_pref_cl)
+ original = n;
+ }
+ else
+ original = n;
continue;
}
}
@@ -1988,7 +2066,39 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
if (original == -1)
goto fail;
if (recog_data.operand_type[original] == OP_OUT)
- return original;
+ {
+ if (pref_cl_alts == 0)
+ return original;
+ /* Visit these recorded alternatives to check whether
+ there is one alternative in which no any INPUT operands
+ have one matching constraint same as our candidate.
+ Give up this candidate if so. */
+ int nop, nalt;
+ for (nalt = 0; nalt < recog_data.n_alternatives; nalt++)
+ {
+ if (!TEST_BIT (pref_cl_alts, nalt))
+ continue;
+ const operand_alternative *op_alt
+ = &recog_op_alt[nalt * recog_data.n_operands];
+ bool dup_in_other = false;
+ for (nop = 0; nop < recog_data.n_operands; nop++)
+ {
+ if (recog_data.operand_type[nop] != OP_IN)
+ continue;
+ if (nop == op_num)
+ continue;
+ if (op_alt[nop].matches == original)
+ {
+ dup_in_other = true;
+ break;
+ }
+ }
+ if (!dup_in_other)
+ return -1;
+ }
+ single_input_op_has_cstr_p = false;
+ return original;
+ }
fail:
if (use_commut_op_p)
break;
diff --git a/gcc/match.pd b/gcc/match.pd
index 8205271..beb8d27 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1458,8 +1458,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* -(A + B) -> (-B) - A. */
(simplify
(negate (plus:c @0 negate_expr_p@1))
- (if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- && !HONOR_SIGNED_ZEROS (element_mode (type)))
+ (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && !HONOR_SIGNED_ZEROS (type))
(minus (negate @1) @0)))
/* -(A - B) -> B - A. */
@@ -3610,7 +3610,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(complex (convert:itype @0) (negate (convert:itype @1)))))
/* BSWAP simplifications, transforms checked by gcc.dg/builtin-bswap-8.c. */
-(for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32 BUILT_IN_BSWAP64)
+(for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32
+ BUILT_IN_BSWAP64 BUILT_IN_BSWAP128)
(simplify
(bswap (bswap @0))
@0)
@@ -3620,7 +3621,82 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(for bitop (bit_xor bit_ior bit_and)
(simplify
(bswap (bitop:c (bswap @0) @1))
- (bitop @0 (bswap @1)))))
+ (bitop @0 (bswap @1))))
+ /* (bswap(x) >> C1) & C2 can sometimes be simplified to (x >> C3) & C2. */
+ (simplify
+ (bit_and (convert1? (rshift@0 (convert2? (bswap@4 @1)) INTEGER_CST@2))
+ INTEGER_CST@3)
+ (if (BITS_PER_UNIT == 8
+ && tree_fits_uhwi_p (@2)
+ && tree_fits_uhwi_p (@3))
+ (with
+ {
+ unsigned HOST_WIDE_INT prec = TYPE_PRECISION (TREE_TYPE (@4));
+ unsigned HOST_WIDE_INT bits = tree_to_uhwi (@2);
+ unsigned HOST_WIDE_INT mask = tree_to_uhwi (@3);
+ unsigned HOST_WIDE_INT lo = bits & 7;
+ unsigned HOST_WIDE_INT hi = bits - lo;
+ }
+ (if (bits < prec
+ && mask < (256u>>lo)
+ && bits < TYPE_PRECISION (TREE_TYPE(@0)))
+ (with { unsigned HOST_WIDE_INT ns = (prec - (hi + 8)) + lo; }
+ (if (ns == 0)
+ (bit_and (convert @1) @3)
+ (with
+ {
+ tree utype = unsigned_type_for (TREE_TYPE (@1));
+ tree nst = build_int_cst (integer_type_node, ns);
+ }
+ (bit_and (convert (rshift:utype (convert:utype @1) {nst;})) @3))))))))
+ /* bswap(x) >> C1 can sometimes be simplified to (T)x >> C2. */
+ (simplify
+ (rshift (convert? (bswap@2 @0)) INTEGER_CST@1)
+ (if (BITS_PER_UNIT == 8
+ && CHAR_TYPE_SIZE == 8
+ && tree_fits_uhwi_p (@1))
+ (with
+ {
+ unsigned HOST_WIDE_INT prec = TYPE_PRECISION (TREE_TYPE (@2));
+ unsigned HOST_WIDE_INT bits = tree_to_uhwi (@1);
+ /* If the bswap was extended before the original shift, this
+ byte (shift) has the sign of the extension, not the sign of
+ the original shift. */
+ tree st = TYPE_PRECISION (type) > prec ? TREE_TYPE (@2) : type;
+ }
+ /* Special case: logical right shift of sign-extended bswap.
+ (unsigned)(short)bswap16(x)>>12 is (unsigned)((short)x<<8)>>12. */
+ (if (TYPE_PRECISION (type) > prec
+ && !TYPE_UNSIGNED (TREE_TYPE (@2))
+ && TYPE_UNSIGNED (type)
+ && bits < prec && bits + 8 >= prec)
+ (with { tree nst = build_int_cst (integer_type_node, prec - 8); }
+ (rshift (convert (lshift:st (convert:st @0) {nst;})) @1))
+ (if (bits + 8 == prec)
+ (if (TYPE_UNSIGNED (st))
+ (convert (convert:unsigned_char_type_node @0))
+ (convert (convert:signed_char_type_node @0)))
+ (if (bits < prec && bits + 8 > prec)
+ (with
+ {
+ tree nst = build_int_cst (integer_type_node, bits & 7);
+ tree bt = TYPE_UNSIGNED (st) ? unsigned_char_type_node
+ : signed_char_type_node;
+ }
+ (convert (rshift:bt (convert:bt @0) {nst;})))))))))
+ /* bswap(x) & C1 can sometimes be simplified to (x >> C2) & C1. */
+ (simplify
+ (bit_and (convert? (bswap@2 @0)) INTEGER_CST@1)
+ (if (BITS_PER_UNIT == 8
+ && tree_fits_uhwi_p (@1)
+ && tree_to_uhwi (@1) < 256)
+ (with
+ {
+ unsigned HOST_WIDE_INT prec = TYPE_PRECISION (TREE_TYPE (@2));
+ tree utype = unsigned_type_for (TREE_TYPE (@0));
+ tree nst = build_int_cst (integer_type_node, prec - 8);
+ }
+ (bit_and (convert (rshift:utype (convert:utype @0) {nst;})) @1)))))
/* Combine COND_EXPRs and VEC_COND_EXPRs. */
@@ -3976,6 +4052,66 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cnd (logical_inverted_value truth_valued_p@0) @1 @2)
(cnd @0 @2 @1)))
+/* abs/negative simplifications moved from fold_cond_expr_with_comparison,
+ Need to handle (A - B) case as fold_cond_expr_with_comparison does.
+ Need to handle UN* comparisons.
+
+ None of these transformations work for modes with signed
+ zeros. If A is +/-0, the first two transformations will
+ change the sign of the result (from +0 to -0, or vice
+ versa). The last four will fix the sign of the result,
+ even though the original expressions could be positive or
+ negative, depending on the sign of A.
+
+ Note that all these transformations are correct if A is
+ NaN, since the two alternatives (A and -A) are also NaNs. */
+
+(for cnd (cond vec_cond)
+ /* A == 0 ? A : -A same as -A */
+ (for cmp (eq uneq)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate@1 @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @1))
+ (simplify
+ (cnd (cmp @0 zerop) integer_zerop (negate@1 @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @1))
+ )
+ /* A != 0 ? A : -A same as A */
+ (for cmp (ne ltgt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @0))
+ (simplify
+ (cnd (cmp @0 zerop) @0 integer_zerop)
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @0))
+ )
+ /* A >=/> 0 ? A : -A same as abs (A) */
+ (for cmp (ge gt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (abs @0))))
+ /* A <=/< 0 ? A : -A same as -abs (A) */
+ (for cmp (le lt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (if (ANY_INTEGRAL_TYPE_P (type)
+ && !TYPE_OVERFLOW_WRAPS (type))
+ (with {
+ tree utype = unsigned_type_for (type);
+ }
+ (convert (negate (absu:utype @0))))
+ (negate (abs @0)))))
+ )
+)
+
/* -(type)!A -> (type)A - 1. */
(simplify
(negate (convert?:s (logical_inverted_value:s @0)))
@@ -6051,7 +6187,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (types_match (@1, @2)
/* Or the second operand is const integer or converted const
integer from valueize. */
- || TREE_CODE (@2) == INTEGER_CST))
+ || poly_int_tree_p (@4)))
(if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
(op @1 (convert @2))
(with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 410a4a6..e7049c8 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -6505,11 +6505,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (code == MINUS_EXPR)
code = PLUS_EXPR;
- /* C/C++ permits FP/complex with || and &&. */
- bool is_fp_and_or
- = ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
- && (FLOAT_TYPE_P (TREE_TYPE (new_var))
- || TREE_CODE (TREE_TYPE (new_var)) == COMPLEX_TYPE));
+ bool is_truth_op
+ = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
tree new_vard = new_var;
if (is_simd && omp_is_reference (var))
{
@@ -6560,17 +6557,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
tree ivar2 = ivar;
tree ref2 = ref;
- if (is_fp_and_or)
+ if (is_truth_op)
{
tree zero = build_zero_cst (TREE_TYPE (ivar));
ivar2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, ivar,
+ boolean_type_node, ivar,
zero);
ref2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, ref, zero);
+ boolean_type_node, ref,
+ zero);
}
x = build2 (code, TREE_TYPE (ref), ref2, ivar2);
- if (is_fp_and_or)
+ if (is_truth_op)
x = fold_convert (TREE_TYPE (ref), x);
ref = build_outer_var_ref (var, ctx);
gimplify_assign (ref, x, &llist[1]);
@@ -6592,19 +6590,19 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree ref = build_outer_var_ref (var, ctx);
tree new_var2 = new_var;
tree ref2 = ref;
- if (is_fp_and_or)
+ if (is_truth_op)
{
tree zero = build_zero_cst (TREE_TYPE (new_var));
new_var2
= fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, new_var,
+ boolean_type_node, new_var,
zero);
ref2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, ref,
+ boolean_type_node, ref,
zero);
}
x = build2 (code, TREE_TYPE (ref2), ref2, new_var2);
- if (is_fp_and_or)
+ if (is_truth_op)
x = fold_convert (TREE_TYPE (new_var), x);
ref = build_outer_var_ref (var, ctx);
gimplify_assign (ref, x, dlist);
@@ -7548,12 +7546,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
if (code == MINUS_EXPR)
code = PLUS_EXPR;
- /* C/C++ permits FP/complex with || and &&. */
- bool is_fp_and_or = ((code == TRUTH_ANDIF_EXPR
- || code == TRUTH_ORIF_EXPR)
- && (FLOAT_TYPE_P (TREE_TYPE (new_var))
- || (TREE_CODE (TREE_TYPE (new_var))
- == COMPLEX_TYPE)));
+ bool is_truth_op = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
if (count == 1)
{
tree addr = build_fold_addr_expr_loc (clause_loc, ref);
@@ -7562,17 +7555,17 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
tree new_var2 = new_var;
tree ref2 = ref;
- if (is_fp_and_or)
+ if (is_truth_op)
{
tree zero = build_zero_cst (TREE_TYPE (new_var));
new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, new_var, zero);
- ref2 = fold_build2_loc (clause_loc, NE_EXPR, integer_type_node,
+ boolean_type_node, new_var, zero);
+ ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
ref, zero);
}
x = fold_build2_loc (clause_loc, code, TREE_TYPE (new_var2), ref2,
new_var2);
- if (is_fp_and_or)
+ if (is_truth_op)
x = fold_convert (TREE_TYPE (new_var), x);
x = build2 (OMP_ATOMIC, void_type_node, addr, x);
OMP_ATOMIC_MEMORY_ORDER (x) = OMP_MEMORY_ORDER_RELAXED;
@@ -7680,16 +7673,16 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
{
tree out2 = out;
tree priv2 = priv;
- if (is_fp_and_or)
+ if (is_truth_op)
{
tree zero = build_zero_cst (TREE_TYPE (out));
out2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, out, zero);
+ boolean_type_node, out, zero);
priv2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, priv, zero);
+ boolean_type_node, priv, zero);
}
x = build2 (code, TREE_TYPE (out2), out2, priv2);
- if (is_fp_and_or)
+ if (is_truth_op)
x = fold_convert (TREE_TYPE (out), x);
out = unshare_expr (out);
gimplify_assign (out, x, &sub_seq);
@@ -7726,16 +7719,16 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
{
tree new_var2 = new_var;
tree ref2 = ref;
- if (is_fp_and_or)
+ if (is_truth_op)
{
tree zero = build_zero_cst (TREE_TYPE (new_var));
new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
- integer_type_node, new_var, zero);
- ref2 = fold_build2_loc (clause_loc, NE_EXPR, integer_type_node,
+ boolean_type_node, new_var, zero);
+ ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
ref, zero);
}
x = build2 (code, TREE_TYPE (ref), ref2, new_var2);
- if (is_fp_and_or)
+ if (is_truth_op)
x = fold_convert (TREE_TYPE (new_var), x);
ref = build_outer_var_ref (var, ctx);
gimplify_assign (ref, x, &sub_seq);
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 41ab259..51acc1b 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -408,6 +408,8 @@ 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 (vec_addsub_optab, "vec_addsub$a3")
+OPTAB_D (vec_fmaddsub_optab, "vec_fmaddsub$a4")
+OPTAB_D (vec_fmsubadd_optab, "vec_fmsubadd$a4")
OPTAB_D (sync_add_optab, "sync_add$I$a")
OPTAB_D (sync_and_optab, "sync_and$I$a")
diff --git a/gcc/opts.c b/gcc/opts.c
index f159bb3..25282f7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -575,6 +575,7 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_stores, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fipa_modref, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
diff --git a/gcc/params.opt b/gcc/params.opt
index 18e6036..577cd42 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -330,6 +330,10 @@ Max size of conflict table in MB.
Common Joined UInteger Var(param_ira_max_loops_num) Init(100) Param Optimization
Max loops number for regional RA.
+-param=ira-consider-dup-in-all-alts=
+Common Joined UInteger Var(param_ira_consider_dup_in_all_alts) Init(1) IntegerRange(0, 1) Param Optimization
+Control ira to consider matching constraint (duplicated operand number) heavily in all available alternatives for preferred register class. If it is set as zero, it means ira only respects the matching constraint when it's in the only available alternative with an appropriate register class. Otherwise, it means ira will check all available alternatives for preferred register class even if it has found some choice with an appropriate register class and respect the found qualified matching constraint.
+
-param=iv-always-prune-cand-set-bound=
Common Joined UInteger Var(param_iv_always_prune_cand_set_bound) Init(10) Param Optimization
If number of candidates in the set is smaller, we always try to remove unused ivs during its optimization.
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 97b9843..f8e4c6d 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -687,7 +687,14 @@ static void
build_lt (irange &r, tree type, const wide_int &val)
{
wi::overflow_type ov;
- wide_int lim = wi::sub (val, 1, TYPE_SIGN (type), &ov);
+ wide_int lim;
+ signop sgn = TYPE_SIGN (type);
+
+ // Signed 1 bit cannot represent 1 for subtraction.
+ if (sgn == SIGNED)
+ lim = wi::add (val, -1, sgn, &ov);
+ else
+ lim = wi::sub (val, 1, sgn, &ov);
// If val - 1 underflows, check if X < MIN, which is an empty range.
if (ov)
@@ -710,7 +717,14 @@ static void
build_gt (irange &r, tree type, const wide_int &val)
{
wi::overflow_type ov;
- wide_int lim = wi::add (val, 1, TYPE_SIGN (type), &ov);
+ wide_int lim;
+ signop sgn = TYPE_SIGN (type);
+
+ // Signed 1 bit cannot represent 1 for addition.
+ if (sgn == SIGNED)
+ lim = wi::sub (val, -1, sgn, &ov);
+ else
+ lim = wi::add (val, 1, sgn, &ov);
// If val + 1 overflows, check is for X > MAX, which is an empty range.
if (ov)
r.set_undefined ();
diff --git a/gcc/recog.c b/gcc/recog.c
index eb617f1..2114df8 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1393,7 +1393,7 @@ valid_insn_p (rtx_insn *insn)
return true;
}
-/* Return 1 if OP is a valid general operand for machine mode MODE.
+/* Return true if OP is a valid general operand for machine mode MODE.
This is either a register reference, a memory reference,
or a constant. In the case of a memory reference, the address
is checked for general validity for the target machine.
@@ -1407,7 +1407,7 @@ valid_insn_p (rtx_insn *insn)
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
general_operand (rtx op, machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -1420,12 +1420,12 @@ general_operand (rtx op, machine_mode mode)
if (GET_MODE (op) == VOIDmode && mode != VOIDmode
&& GET_MODE_CLASS (mode) != MODE_INT
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
- return 0;
+ return false;
if (CONST_INT_P (op)
&& mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
- return 0;
+ return false;
if (CONSTANT_P (op))
return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
@@ -1439,7 +1439,7 @@ general_operand (rtx op, machine_mode mode)
OP's mode must match MODE if MODE specifies a mode. */
if (GET_MODE (op) != mode)
- return 0;
+ return false;
if (code == SUBREG)
{
@@ -1452,7 +1452,7 @@ general_operand (rtx op, machine_mode mode)
get cleaned up by cleanup_subreg_operands. */
if (!reload_completed && MEM_P (sub)
&& paradoxical_subreg_p (op))
- return 0;
+ return false;
#endif
/* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
may result in incorrect reference. We should simplify all valid
@@ -1463,7 +1463,7 @@ general_operand (rtx op, machine_mode mode)
if (!reload_completed
&& maybe_ne (SUBREG_BYTE (op), 0)
&& MEM_P (sub))
- return 0;
+ return false;
if (REG_P (sub)
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
@@ -1474,7 +1474,7 @@ general_operand (rtx op, machine_mode mode)
operand reload presentation. LRA needs to treat them as
valid. */
&& ! LRA_SUBREG_P (op))
- return 0;
+ return false;
/* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
create such rtl, and we must reject it. */
@@ -1486,7 +1486,7 @@ general_operand (rtx op, machine_mode mode)
mode. */
&& ! lra_in_progress
&& paradoxical_subreg_p (op))
- return 0;
+ return false;
op = sub;
code = GET_CODE (op);
@@ -1501,7 +1501,7 @@ general_operand (rtx op, machine_mode mode)
rtx y = XEXP (op, 0);
if (! volatile_ok && MEM_VOLATILE_P (op))
- return 0;
+ return false;
/* Use the mem's mode, since it will be reloaded thus. LRA can
generate move insn with invalid addresses which is made valid
@@ -1509,19 +1509,19 @@ general_operand (rtx op, machine_mode mode)
transformations. */
if (lra_in_progress
|| memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-/* Return 1 if OP is a valid memory address for a memory reference
+/* Return true if OP is a valid memory address for a memory reference
of mode MODE.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
address_operand (rtx op, machine_mode mode)
{
/* Wrong mode for an address expr. */
@@ -1532,13 +1532,13 @@ address_operand (rtx op, machine_mode mode)
return memory_address_p (mode, op);
}
-/* Return 1 if OP is a register reference of mode MODE.
+/* Return true if OP is a register reference of mode MODE.
If MODE is VOIDmode, accept a register in any mode.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
register_operand (rtx op, machine_mode mode)
{
if (GET_CODE (op) == SUBREG)
@@ -1552,29 +1552,29 @@ register_operand (rtx op, machine_mode mode)
but currently it does result from (SUBREG (REG)...) where the
reg went on the stack.) */
if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
- return 0;
+ return false;
}
else if (!REG_P (op))
- return 0;
+ return false;
return general_operand (op, mode);
}
-/* Return 1 for a register in Pmode; ignore the tested mode. */
+/* Return true for a register in Pmode; ignore the tested mode. */
-int
+bool
pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
{
return register_operand (op, Pmode);
}
-/* Return 1 if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
+/* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
or a hard register. */
-int
+bool
scratch_operand (rtx op, machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
- return 0;
+ return false;
return (GET_CODE (op) == SCRATCH
|| (REG_P (op)
@@ -1583,12 +1583,12 @@ scratch_operand (rtx op, machine_mode mode)
&& REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
}
-/* Return 1 if OP is a valid immediate operand for mode MODE.
+/* Return true if OP is a valid immediate operand for mode MODE.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
immediate_operand (rtx op, machine_mode mode)
{
/* Don't accept CONST_INT or anything similar
@@ -1596,12 +1596,12 @@ immediate_operand (rtx op, machine_mode mode)
if (GET_MODE (op) == VOIDmode && mode != VOIDmode
&& GET_MODE_CLASS (mode) != MODE_INT
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
- return 0;
+ return false;
if (CONST_INT_P (op)
&& mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
- return 0;
+ return false;
return (CONSTANT_P (op)
&& (GET_MODE (op) == mode || mode == VOIDmode
@@ -1612,29 +1612,29 @@ immediate_operand (rtx op, machine_mode mode)
: mode, op));
}
-/* Returns 1 if OP is an operand that is a CONST_INT of mode MODE. */
+/* Return true if OP is an operand that is a CONST_INT of mode MODE. */
-int
+bool
const_int_operand (rtx op, machine_mode mode)
{
if (!CONST_INT_P (op))
- return 0;
+ return false;
if (mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
- return 0;
+ return false;
- return 1;
+ return true;
}
#if TARGET_SUPPORTS_WIDE_INT
-/* Returns 1 if OP is an operand that is a CONST_INT or CONST_WIDE_INT
+/* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
of mode MODE. */
-int
+bool
const_scalar_int_operand (rtx op, machine_mode mode)
{
if (!CONST_SCALAR_INT_P (op))
- return 0;
+ return false;
if (CONST_INT_P (op))
return const_int_operand (op, mode);
@@ -1646,10 +1646,10 @@ const_scalar_int_operand (rtx op, machine_mode mode)
int bitsize = GET_MODE_BITSIZE (int_mode);
if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
- return 0;
+ return false;
if (prec == bitsize)
- return 1;
+ return true;
else
{
/* Multiword partial int. */
@@ -1658,23 +1658,23 @@ const_scalar_int_operand (rtx op, machine_mode mode)
return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
}
}
- return 1;
+ return true;
}
-/* Returns 1 if OP is an operand that is a constant integer or constant
+/* Return true if OP is an operand that is a constant integer or constant
floating-point number of MODE. */
-int
+bool
const_double_operand (rtx op, machine_mode mode)
{
return (GET_CODE (op) == CONST_DOUBLE)
&& (GET_MODE (op) == mode || mode == VOIDmode);
}
#else
-/* Returns 1 if OP is an operand that is a constant integer or constant
+/* Return true if OP is an operand that is a constant integer or constant
floating-point number of MODE. */
-int
+bool
const_double_operand (rtx op, machine_mode mode)
{
/* Don't accept CONST_INT or anything similar
@@ -1682,25 +1682,26 @@ const_double_operand (rtx op, machine_mode mode)
if (GET_MODE (op) == VOIDmode && mode != VOIDmode
&& GET_MODE_CLASS (mode) != MODE_INT
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
- return 0;
+ return false;
return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
&& (mode == VOIDmode || GET_MODE (op) == mode
|| GET_MODE (op) == VOIDmode));
}
#endif
-/* Return 1 if OP is a general operand that is not an immediate
+/* Return true if OP is a general operand that is not an immediate
operand of mode MODE. */
-int
+bool
nonimmediate_operand (rtx op, machine_mode mode)
{
return (general_operand (op, mode) && ! CONSTANT_P (op));
}
-/* Return 1 if OP is a register reference or immediate value of mode MODE. */
+/* Return true if OP is a register reference or
+ immediate value of mode MODE. */
-int
+bool
nonmemory_operand (rtx op, machine_mode mode)
{
if (CONSTANT_P (op))
@@ -1708,20 +1709,20 @@ nonmemory_operand (rtx op, machine_mode mode)
return register_operand (op, mode);
}
-/* Return 1 if OP is a valid operand that stands for pushing a
+/* Return true if OP is a valid operand that stands for pushing a
value of mode MODE onto the stack.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
push_operand (rtx op, machine_mode mode)
{
if (!MEM_P (op))
- return 0;
+ return false;
if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
+ return false;
poly_int64 rounded_size = GET_MODE_SIZE (mode);
@@ -1734,7 +1735,7 @@ push_operand (rtx op, machine_mode mode)
if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
{
if (GET_CODE (op) != STACK_PUSH_CODE)
- return 0;
+ return false;
}
else
{
@@ -1746,31 +1747,31 @@ push_operand (rtx op, machine_mode mode)
|| (STACK_GROWS_DOWNWARD
? maybe_ne (offset, -rounded_size)
: maybe_ne (offset, rounded_size)))
- return 0;
+ return false;
}
return XEXP (op, 0) == stack_pointer_rtx;
}
-/* Return 1 if OP is a valid operand that stands for popping a
+/* Return true if OP is a valid operand that stands for popping a
value of mode MODE off the stack.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
pop_operand (rtx op, machine_mode mode)
{
if (!MEM_P (op))
- return 0;
+ return false;
if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
+ return false;
op = XEXP (op, 0);
if (GET_CODE (op) != STACK_POP_CODE)
- return 0;
+ return false;
return XEXP (op, 0) == stack_pointer_rtx;
}
@@ -1794,13 +1795,13 @@ memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
#endif
}
-/* Return 1 if OP is a valid memory reference with mode MODE,
+/* Return true if OP is a valid memory reference with mode MODE,
including a valid address.
The main use of this function is as a predicate in match_operand
expressions in the machine description. */
-int
+bool
memory_operand (rtx op, machine_mode mode)
{
rtx inner;
@@ -1811,7 +1812,7 @@ memory_operand (rtx op, machine_mode mode)
return MEM_P (op) && general_operand (op, mode);
if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
+ return false;
inner = op;
if (GET_CODE (inner) == SUBREG)
@@ -1820,10 +1821,10 @@ memory_operand (rtx op, machine_mode mode)
return (MEM_P (inner) && general_operand (op, mode));
}
-/* Return 1 if OP is a valid indirect memory reference with mode MODE;
+/* Return true if OP is a valid indirect memory reference with mode MODE;
that is, a memory reference whose address is a general_operand. */
-int
+bool
indirect_operand (rtx op, machine_mode mode)
{
/* Before reload, a SUBREG isn't in memory (see memory_operand, above). */
@@ -1831,7 +1832,7 @@ indirect_operand (rtx op, machine_mode mode)
&& GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
{
if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
+ return false;
/* The only way that we can have a general_operand as the resulting
address is if OFFSET is zero and the address already is an operand
@@ -1848,10 +1849,10 @@ indirect_operand (rtx op, machine_mode mode)
&& general_operand (XEXP (op, 0), Pmode));
}
-/* Return 1 if this is an ordered comparison operator (not including
+/* Return true if this is an ordered comparison operator (not including
ORDERED and UNORDERED). */
-int
+bool
ordered_comparison_operator (rtx op, machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
@@ -1874,10 +1875,10 @@ ordered_comparison_operator (rtx op, machine_mode mode)
}
}
-/* Return 1 if this is a comparison operator. This allows the use of
+/* Return true if this is a comparison operator. This allows the use of
MATCH_OPERATOR to recognize all the branch insns. */
-int
+bool
comparison_operator (rtx op, machine_mode mode)
{
return ((mode == VOIDmode || GET_MODE (op) == mode)
diff --git a/gcc/recog.h b/gcc/recog.h
index e96e66e..653d0b0 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -393,7 +393,7 @@ which_op_alt ()
/* A table defined in insn-output.c that give information about
each insn-code value. */
-typedef int (*insn_operand_predicate_fn) (rtx, machine_mode);
+typedef bool (*insn_operand_predicate_fn) (rtx, machine_mode);
typedef const char * (*insn_output_fn) (rtx *, rtx_insn *);
struct insn_gen_fn
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 51fc7ad..cac4995 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,568 @@
+2021-07-10 John David Anglin <danglin@gcc.gnu.org>
+
+ * gcc.dg/torture/pr100329.c: Require target lra.
+ * gcc.dg/torture/pr100519.c: Likewise.
+
+2021-07-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/82110
+ * g++.dg/cpp0x/pr78765.C: Expect another conversion failure
+ diagnostic.
+ * g++.dg/template/sfinae14.C: Flip incorrect assertion.
+ * g++.dg/cpp2a/concepts-requires27.C: New test.
+
+2021-07-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/101098
+ * g++.dg/concepts/explicit-spec1.C: New test.
+
+2021-07-09 Roger Sayle <roger@nextmovesoftware.com>
+ Uroš Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/divmod-9.c: New test case.
+
+2021-07-09 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR testsuite/101269
+ * gcc.dg/debug/btf/btf-datasec-1.c: Force -msdata=none with ilp32 for
+ powerpc based targets.
+
+2021-07-09 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101181
+ * g++.dg/cpp2a/concepts-requires26.C: New test.
+ * g++.dg/cpp2a/lambda-uneval16.C: New test.
+
+2021-07-09 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101247
+ * g++.dg/cpp2a/concepts-memtmpl4.C: Uncomment the commented out
+ example, which we now handle correctly.
+ * g++.dg/cpp2a/concepts-memtmpl5.C: New test.
+ * g++.dg/cpp2a/concepts-memtmpl5a.C: New test.
+
+2021-07-09 Xi Ruoyao <xry111@mengyan1223.wang>
+
+ * gcc.target/mips/cfgcleanup-jalr2.c: Remove -fno-inline and add
+ __attribute__((noinline)).
+ * gcc.target/mips/cfgcleanup-jalr3.c: Likewise.
+
+2021-07-09 Xi Ruoyao <xry111@mengyan1223.wang>
+
+ PR target/100760
+ PR target/100761
+ PR target/100762
+ * gcc.target/mips/pr100760.c: New test.
+ * gcc.target/mips/pr100761.c: New test.
+ * gcc.target/mips/pr100762.c: New test.
+
+2021-07-09 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.target/powerpc/mod-vectorize.c: New test.
+
+2021-07-09 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.target/powerpc/div-vectorize-1.c: New test.
+
+2021-07-09 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.target/powerpc/mul-vectorize-1.c: New test.
+ * gcc.target/powerpc/mul-vectorize-2.c: New test.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/Wstringop-overflow-43.c: Remove an xfail.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR testsuite/100451
+ * g++.dg/warn/Warray-bounds-20.C: Adjust expected output for LP32.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ * g++.dg/warn/Warray-bounds-11.C: Avoid including <new>.
+ * g++.dg/warn/Warray-bounds-13.C: Same.
+
+2021-07-08 Marek Polacek <polacek@redhat.com>
+
+ PR c++/101087
+ * g++.dg/cpp0x/noexcept70.C: New test.
+
+2021-07-08 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/101066
+ * gcc.dg/ipa/pr101066.c: New test.
+
+2021-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/101374
+ * c-c++-common/Warray-bounds-3.c: Xfail assertion.
+ * c-c++-common/Warray-bounds-4.c: Same.
+
+2021-07-08 Christophe Lyon <christophe.lyon@foss.st.om>
+
+ * gcc.dg/debug/pr57351.c: Require arm_arch_v7a_ok
+ effective-target.
+
+2021-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/cntb_1.c: New test.
+
+2021-07-08 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/40210
+ * gcc.dg/builtin-bswap-13.c: New test.
+ * gcc.dg/builtin-bswap-14.c: New test.
+
+2021-07-08 Michael Meissner <meissner@linux.ibm.com>
+
+ PR target/100809
+ * gcc.target/powerpc/p10-vdivq-vmodq.c: New test.
+
+2021-07-07 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/pattern-test-2.c: Update expected results.
+ * gcc.dg/plugin/analyzer_gil_plugin.c
+ (gil_state_machine::on_condition): Remove.
+
+2021-07-07 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/100137
+ PR tree-optimization/99121
+ PR tree-optimization/97027
+ * c-c++-common/Warray-bounds-3.c: Remove xfail
+ * c-c++-common/Warray-bounds-4.c: Add an expected warning.
+ * c-c++-common/Warray-bounds-9.c: New test.
+ * c-c++-common/Warray-bounds-10.c: New test.
+ * g++.dg/asan/asan_test.C: Suppress expected warnings.
+ * g++.dg/pr95768.C: Same.
+ * g++.dg/warn/Warray-bounds-10.C: Adjust text of expected messages.
+ * g++.dg/warn/Warray-bounds-11.C: Same.
+ * g++.dg/warn/Warray-bounds-12.C: Same.
+ * g++.dg/warn/Warray-bounds-13.C: Same.
+ * g++.dg/warn/Warray-bounds-17.C: Same.
+ * g++.dg/warn/Warray-bounds-20.C: Same.
+ * gcc.dg/Warray-bounds-29.c: Same.
+ * gcc.dg/Warray-bounds-30.c: Add xfail.
+ * gcc.dg/Warray-bounds-31.c: Adjust text of expected messages.
+ * gcc.dg/Warray-bounds-32.c: Same.
+ * gcc.dg/Warray-bounds-52.c: Same.
+ * gcc.dg/Warray-bounds-53.c: Same.
+ * gcc.dg/Warray-bounds-58.c: Remove xfail.
+ * gcc.dg/Warray-bounds-63.c: Adjust text of expected messages.
+ * gcc.dg/Warray-bounds-66.c: Same.
+ * gcc.dg/Warray-bounds-69.c: Same.
+ * gcc.dg/Wstringop-overflow-34.c: Same.
+ * gcc.dg/Wstringop-overflow-47.c: Same.
+ * gcc.dg/Wstringop-overflow-61.c: Same.
+ * gcc.dg/Warray-bounds-77.c: New test.
+ * gcc.dg/Warray-bounds-78.c: New test.
+ * gcc.dg/Warray-bounds-79.c: New test.
+
+2021-07-07 Christophe Lyon <christophe.lyon@foss.st.com>
+
+ PR debug/101321
+ * gcc.dg/debug/btf/btf-bitfields-3.c: Remove -fno-short-enums.
+
+2021-07-07 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/34195
+ * gcc.dg/vect/pr34195.c: New testcase.
+
+2021-07-07 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/99728
+ * g++.dg/opt/pr99728.C: New testcase.
+
+2021-07-07 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avx512f-vect-fmaddsubXXXpd.c: New test.
+ * gcc.target/i386/avx512f-vect-fmaddsubXXXps.c: New test.
+ * gcc.target/i386/avx512f-vect-fmsubaddXXXpd.c: New test.
+ * gcc.target/i386/avx512f-vect-fmsubaddXXXps.c: New test.
+
+2021-07-06 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR debug/101283
+ * gcc.dg/debug/btf/btf-bitfields-3.c: Remove the check on btm_type.
+
+2021-07-06 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR debug/101283
+ * gcc.dg/debug/ctf/ctf-attr-mode-1.c: Remove the check for ctv_typeidx.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ PR c++/55881
+ * g++.dg/warn/uninit-pr55881.C: New test.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/86650
+ * gcc.dg/Warray-bounds-76.c: New test.
+
+2021-07-06 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR debug/101283
+ * gcc.dg/debug/ctf/ctf-struct-array-2.c: Adjust the value in the testcase.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/format/gcc_diag-10.c: Update expected warnings.
+ * gcc.dg/plugin/diagnostic_plugin_test_inlining.c: Remove %G.
+
+2021-07-06 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/Wobjsize-1.c: Prune expected output.
+ * gcc.dg/Warray-bounds-71.c: New test.
+ * gcc.dg/Warray-bounds-71.h: New test header.
+ * gcc.dg/Warray-bounds-72.c: New test.
+ * gcc.dg/Warray-bounds-73.c: New test.
+ * gcc.dg/Warray-bounds-74.c: New test.
+ * gcc.dg/Warray-bounds-75.c: New test.
+ * gcc.dg/Wfree-nonheap-object-4.c: Adjust expected output.
+ * gcc.dg/Wfree-nonheap-object-5.c: New test.
+ * gcc.dg/Wfree-nonheap-object-6.c: New test.
+ * gcc.dg/pragma-diag-10.c: New test.
+ * gcc.dg/pragma-diag-9.c: New test.
+ * gcc.dg/uninit-suppress_3.c: New test.
+ * gcc.dg/pr79214.c: Xfail tests.
+ * gcc.dg/tree-ssa/builtin-sprintf-warn-27.c: New test.
+ * gcc.dg/format/c90-printf-1.c: Adjust expected output.
+
+2021-07-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97194
+ * gcc.target/i386/sse4_1-vec-set-1a.c: New test.
+ * gcc.target/i386/sse4_1-vec-set-2a.c: Ditto.
+
+2021-07-06 Richard Biener <rguenther@suse.de>
+
+ * gcc.target/i386/vect-fmaddsubXXXpd.c: New testcase.
+ * gcc.target/i386/vect-fmaddsubXXXps.c: Likewise.
+ * gcc.target/i386/vect-fmsubaddXXXpd.c: Likewise.
+ * gcc.target/i386/vect-fmsubaddXXXps.c: Likewise.
+
+2021-07-06 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101256
+ * g++.dg/torture/pr101256.C: New test.
+
+2021-07-06 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/100227
+ * gfortran.dg/implied_do_io_7.f90: New test.
+
+2021-07-06 Kewen Lin <linkw@linux.ibm.com>
+
+ PR rtl-optimization/100328
+ * gcc.target/aarch64/sve/acle/asm/div_f16.c: Remove one xfail.
+ * gcc.target/aarch64/sve/acle/asm/div_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/div_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/divr_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/divr_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/divr_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mad_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mad_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mad_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mla_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mla_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mla_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mls_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mls_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mls_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/msb_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/msb_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/msb_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mulx_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mulx_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/mulx_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmad_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmad_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmad_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmla_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmla_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmla_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmls_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmls_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmls_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmsb_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmsb_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/nmsb_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/sub_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/sub_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/sub_f64.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/subr_f16.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/subr_f32.c: Likewise.
+ * gcc.target/aarch64/sve/acle/asm/subr_f64.c: Likewise.
+
+2021-07-06 Indu Bhagat <indu.bhagat@oracle.com>
+
+ PR debug/101283
+ * gcc.dg/debug/btf/btf-cvr-quals-1.c: Use -gdwarf-4 on Darwin targets.
+ * gcc.dg/debug/ctf/ctf-cvr-quals-1.c: Likewise.
+
+2021-07-05 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/101039
+ * gcc.dg/tree-ssa/phi-opt-15.c: Update test to expect
+ ABSU and still not expect ABS_EXPR.
+ * gcc.dg/tree-ssa/phi-opt-23.c: New test.
+ * gcc.dg/tree-ssa/phi-opt-24.c: New test.
+
+2021-07-05 Christophe Lyon <christophe.lyon@foss.st.com>
+
+ PR debug/101321
+ * gcc.dg/debug/btf/btf-bitfields-3.c: Add -fno-short-enums.
+
+2021-07-05 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/101299
+ * gcc.dg/vect/bb-slp-74.c: Add vect_double requires.
+
+2021-07-05 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr92658-avx512vl.c: Refine testcase.
+
+2021-07-03 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/debug/btf/btf.exp: Skip on AIX.
+ * gcc.dg/debug/ctf/ctf.exp: Skip on AIX.
+ * lib/gcc-dg.exp (gcc-dg-target-supports-debug-format): AIX
+ doesn't support CTF.
+ (gcc-dg-debug-runtest): Move CTF support within
+ target support format test.
+
+2021-07-03 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/101294
+ * gcc.dg/pr101294.c: New test.
+
+2021-07-03 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/101273
+ * gdc.dg/torture/pr101273.d: New test.
+
+2021-07-02 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/101282
+ * gdc.dg/torture/pr101282.d: New test.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/gomp/attrs-1.C: New test.
+ * g++.dg/gomp/attrs-2.C: New test.
+ * g++.dg/gomp/attrs-3.C: New test.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/101297
+ * c-c++-common/gomp/atomic-24.c: New test.
+
+2021-07-02 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101247
+ * g++.dg/cpp2a/concepts-memtmpl4.C: New test.
+
+2021-07-02 Peter Bergner <bergner@linux.ibm.com>
+
+ * gcc.target/powerpc/mma-builtin-7.c: New test.
+ * gcc.target/powerpc/mma-builtin-8.c: New test.
+
+2021-07-02 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/101223
+ * gcc.dg/pr101223.c: New.
+
+2021-07-02 David Faust <david.faust@oracle.com>
+
+ * gcc.dg/debug/btf/btf-float-1.c: New test.
+ * gcc.dg/debug/btf/btf-function-3.c: Use different unrepresentable type.
+ * gcc.dg/debug/btf/btf-struct-2.c: Likewise.
+ * gcc.dg/debug/btf/btf-variables-2.c: Likewise.
+
+2021-07-02 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
+
+ * lib/gcc-defs.exp: Add a comment.
+
+2021-07-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101293
+ * gcc.dg/tree-ssa/ssa-lim-15.c: New testcase.
+
+2021-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/101286
+ * gcc.target/i386/avx2-pr101286.c: New test.
+
+2021-07-02 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/keylocker-aesdec128kl.c: Update test.
+ * 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-aesenc256kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesencwide128kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesencwide256kl.c: Likewise.
+
+2021-07-01 Michael Meissner <meissner@linux.ibm.com>
+
+ * gcc.target/powerpc/float128-cmove.c: New test.
+ * gcc.target/powerpc/float128-minmax-3.c: New test.
+
+2021-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-c++-common/dump-ada-spec-14.c: Adjust dg-warning directive.
+
+2021-07-01 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/100865
+ * gcc.target/i386/avx512f-broadcast-pr87767-1.c: Expect integer
+ broadcast.
+ * gcc.target/i386/avx512f-broadcast-pr87767-5.c: Likewise.
+ * gcc.target/i386/avx512vl-broadcast-pr87767-1.c: Likewise.
+ * gcc.target/i386/avx512vl-broadcast-pr87767-5.c: Likewise.
+ * gcc.target/i386/avx512f_cond_move.c: Also pass
+ -mprefer-vector-width=512 and expect integer broadcast.
+ * gcc.target/i386/pr100865-1.c: New test.
+ * gcc.target/i386/pr100865-2.c: Likewise.
+ * gcc.target/i386/pr100865-3.c: Likewise.
+ * gcc.target/i386/pr100865-4a.c: Likewise.
+ * gcc.target/i386/pr100865-4b.c: Likewise.
+ * gcc.target/i386/pr100865-5a.c: Likewise.
+ * gcc.target/i386/pr100865-5b.c: Likewise.
+ * gcc.target/i386/pr100865-6a.c: Likewise.
+ * gcc.target/i386/pr100865-6b.c: Likewise.
+ * gcc.target/i386/pr100865-6c.c: Likewise.
+ * gcc.target/i386/pr100865-7a.c: Likewise.
+ * gcc.target/i386/pr100865-7b.c: Likewise.
+ * gcc.target/i386/pr100865-7c.c: Likewise.
+ * gcc.target/i386/pr100865-8a.c: Likewise.
+ * gcc.target/i386/pr100865-8b.c: Likewise.
+ * gcc.target/i386/pr100865-8c.c: Likewise.
+ * gcc.target/i386/pr100865-9a.c: Likewise.
+ * gcc.target/i386/pr100865-9b.c: Likewise.
+ * gcc.target/i386/pr100865-9c.c: Likewise.
+ * gcc.target/i386/pr100865-10a.c: Likewise.
+ * gcc.target/i386/pr100865-10b.c: Likewise.
+ * gcc.target/i386/pr100865-11a.c: Likewise.
+ * gcc.target/i386/pr100865-11b.c: Likewise.
+ * gcc.target/i386/pr100865-11c.c: Likewise.
+ * gcc.target/i386/pr100865-12a.c: Likewise.
+ * gcc.target/i386/pr100865-12b.c: Likewise.
+ * gcc.target/i386/pr100865-12c.c: Likewise.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101280
+ PR tree-optimization/101173
+ * gcc.dg/tree-ssa/loop-interchange-16.c: New testcase.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101278
+ * gcc.dg/torture/pr101278.c: New testcase.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/100778
+ * gcc.dg/torture/pr100778.c: New testcase.
+
+2021-07-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/101044
+ * gcc.target/i386/pr101044.c: New test.
+
+2021-07-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101178
+ * gcc.dg/vect/bb-slp-72.c: New testcase.
+ * gcc.dg/vect/bb-slp-73.c: Likewise.
+ * gcc.dg/vect/bb-slp-74.c: Likewise.
+
+2021-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/101266
+ * gcc.dg/pr101266.c: New test.
+
+2021-07-01 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101194
+ * g++.dg/cpp0x/constexpr-empty16.C: New test.
+
+2021-07-01 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/96204
+ * g++.dg/template/access41.C: New test.
+ * g++.dg/template/access41a.C: New test.
+
+2021-06-30 Indu Bhagat <indu.bhagat@oracle.com>
+
+ * gcc.dg/debug/ctf/ctf-skip-types-4.c: Add dg-add-options float64 and
+ float64x.
+
+2021-06-30 Michael Meissner <meissner@linux.ibm.com>
+
+ * gcc.target/powerpc/float128-minmax.c: Adjust expected code for
+ power10.
+ * lib/target-supports.exp (check_effective_target_has_arch_pwr10):
+ New.
+
+2021-06-30 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/cpp2a/concepts-access2.C: New test.
+
+2021-06-30 Marek Polacek <polacek@redhat.com>
+
+ PR c++/100975
+ DR 2397
+ * g++.dg/cpp0x/auto24.C: Remove dg-error.
+ * g++.dg/cpp0x/auto3.C: Adjust dg-error.
+ * g++.dg/cpp0x/auto42.C: Likewise.
+ * g++.dg/cpp0x/initlist75.C: Likewise.
+ * g++.dg/cpp0x/initlist80.C: Likewise.
+ * g++.dg/diagnostic/auto1.C: Remove dg-error.
+ * g++.dg/cpp23/auto-array.C: New test.
+
+2021-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101267
+ * gfortran.dg/pr101267.f90: New testcase.
+
+2021-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/95006
+ * gcc.dg/analyzer/clobbers-1.c: New test.
+ * gcc.dg/analyzer/clobbers-2.c: New test.
+ * gcc.dg/analyzer/data-model-1.c (test_26): Mark xfail as fixed.
+ (test_28): Likewise.
+ (test_52): Likewise. Add coverage for end of buffer.
+ * gcc.dg/analyzer/explode-1.c: Add leak warning.
+ * gcc.dg/analyzer/memset-1.c (test_3): Mark xfail as fixed.
+ (test_4): Use char. Mark xfail as fixed.
+ (test_6b): New.
+ (test_7): Mark xfail as fixed. Add coverage for start of buffer.
+ (test_8): New.
+ (test_9): New.
+ * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: New test.
+ * gcc.dg/analyzer/symbolic-8.c: New test.
+
+2021-06-30 Christophe Lyon <christophe.lyon@foss.st.com>
+
+ * gcc.dg/debug/ctf/ctf-skip-types-2.c: Add dg-add-options float16.
+
+2021-06-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101264
+ * gfortran.dg/pr101264.f90: New testcase.
+
+2021-06-30 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101248
+ * gcc.target/i386/pr101248.c: New test.
+
2021-06-29 Andrew MacLeod <amacleod@redhat.com>
* gcc.dg/pr101254.c: New.
diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-10.c b/gcc/testsuite/c-c++-common/Warray-bounds-10.c
new file mode 100644
index 0000000..cfe9a38
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Warray-bounds-10.c
@@ -0,0 +1,114 @@
+/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
+ element of empty structs
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct S
+{
+#if SOME_CONFIG_MACRO
+ /* Suppose the contents are empty in the development configuration
+ but non-empty in others. Out of bounds accesses to elements of
+ the arrays below should be diagnosed in all configurations,
+ including when S is empty, even if they are folded away. */
+ int member;
+#endif
+};
+
+extern struct S sa3[3];
+extern struct S sa2_3[2][3];
+extern struct S sa3_4_5[3][4][5];
+
+void sink (void*);
+
+
+void access_sa3 (struct S s)
+{
+ sa3[0] = s;
+ sa3[1] = s;
+ sa3[2] = s;
+ sa3[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa3_ptr (struct S s)
+{
+ struct S *p = &sa3[0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa2_3_ptr (struct S s)
+{
+ struct S *p = &sa2_3[0][0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[6] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa3_4_5_ptr (struct S s, int i)
+{
+ struct S *p = &sa3_4_5[0][0][0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[60] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+
+void access_vla3 (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+
+ vla3[0] = s;
+ vla3[1] = s;
+ vla3[2] = s;
+ vla3[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3);
+}
+
+void access_vla3_ptr (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+ struct S *p = &vla3[0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3);
+}
+
+void access_vla2_3_ptr (struct S s, unsigned n)
+{
+ struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
+ struct S *p = &vla2_3[0][0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[6] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla2_3);
+}
+
+void access_vla3_4_5_ptr (struct S s, unsigned n)
+{
+ struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
+ struct S *p = &vla3_4_5[0][0][0];
+
+ p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
+ p[60] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3_4_5);
+}
+
+// { dg-prune-output "empty struct has size 0 in C" }
diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-3.c b/gcc/testsuite/c-c++-common/Warray-bounds-3.c
index aae4999..75f9a49 100644
--- a/gcc/testsuite/c-c++-common/Warray-bounds-3.c
+++ b/gcc/testsuite/c-c++-common/Warray-bounds-3.c
@@ -158,7 +158,7 @@ void test_memcpy_overflow (char *d, const char *s, size_t n)
but known access size is detected. This works except with small
sizes that are powers of 2 due to bug . */
T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1);
- T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail non_strict_align } } */
+ T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "\\\[-Warray-bounds" } */
T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */
T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */
}
@@ -178,7 +178,7 @@ void test_memcpy_bounds_memarray_range (void)
TM (ma.a5, ma.a5 + i, ma.a5, 1);
TM (ma.a5, ma.a5 + i, ma.a5, 3);
- TM (ma.a5, ma.a5 + i, ma.a5, 5);
+ TM (ma.a5, ma.a5 + i, ma.a5, 5); /* { dg-warning "\\\[-Warray-bounds" "pr101374" { xfail *-*-* } } */
TM (ma.a5, ma.a5 + i, ma.a5, 7); /* diagnosed with -Warray-bounds=2 */
}
diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-4.c b/gcc/testsuite/c-c++-common/Warray-bounds-4.c
index 22a23a1..835c634 100644
--- a/gcc/testsuite/c-c++-common/Warray-bounds-4.c
+++ b/gcc/testsuite/c-c++-common/Warray-bounds-4.c
@@ -43,7 +43,17 @@ void test_memcpy_bounds_memarray_range (void)
TM (ma.a5, ma.a5 + j, ma.a5, 1);
TM (ma.a5, ma.a5 + j, ma.a5, 3);
- TM (ma.a5, ma.a5 + j, ma.a5, 5);
+
+ /* The copy below is invalid for two reasons: 1) it overlaps and 2) it
+ writes past the end of ma.a5. The warning is a little cryptic here
+ because the GIMPLE is:
+ _4 = &ma.a5 + prephitmp_14;
+ MEM <unsigned char[5]> [(char * {ref-all})_4]
+ = MEM <unsigned char[5]> [(char * {ref-all})&ma];
+ and could be improved. Just verify that one is issued but not its
+ full text. */
+ TM (ma.a5, ma.a5 + j, ma.a5, 5); /* { dg-warning "\\\[-Warray-bounds" "pr101374" { xfail *-*-* } } */
+
TM (ma.a5, ma.a5 + j, ma.a5, 7); /* { dg-warning "offset \\\[5, 7] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
TM (ma.a5, ma.a5 + j, ma.a5, 9); /* { dg-warning "offset \\\[5, 9] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
}
diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-9.c b/gcc/testsuite/c-c++-common/Warray-bounds-9.c
new file mode 100644
index 0000000..be05775
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Warray-bounds-9.c
@@ -0,0 +1,144 @@
+/* PR tree-optimization/99121 - ICE in -Warray-bounds on a multidimensional
+ VLA
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void sink (void*, ...);
+#define T(a, x) sink (a, x)
+
+
+NOIPA void a_0_n (int n)
+{
+ int a[0][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_n_0 (int n)
+{
+ int a[n][0];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+
+NOIPA void a_1_n_0 (int n)
+{
+ int a[1][n][0];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_1_0_n (int n)
+{
+ int a[1][0][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_0_1_n (int n)
+{
+ int a[0][1][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_0_n_1 (int n)
+{
+ int a[0][n][1];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_n_0_n (int n)
+{
+ int a[n][0][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_n_n_0 (int n)
+{
+ int a[n][n][0];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_0_n_n (int n)
+{
+ int a[0][n][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_0_0_n (int n)
+{
+ int a[0][0][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_n_0_0 (int n)
+{
+ int a[n][0][0];
+
+ sink (a);
+
+ T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
+ T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void a_n_n_n (int n)
+{
+ int a[n][n][n];
+
+ sink (a);
+
+ T (a, ((int *) a)[-1]); // { dg-warning "\\\[-Warray-bounds" "pr99140" }
+ T (a, ((int *) a)[0]);
+ T (a, ((char *) a)[1]);
+ T (a, ((float *) a)[n]);
+}
diff --git a/gcc/testsuite/c-c++-common/dump-ada-spec-14.c b/gcc/testsuite/c-c++-common/dump-ada-spec-14.c
index bfdec61..291eea8 100644
--- a/gcc/testsuite/c-c++-common/dump-ada-spec-14.c
+++ b/gcc/testsuite/c-c++-common/dump-ada-spec-14.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-fdump-ada-spec" } */
-struct __attribute__((packed)) S /* { dg-warning "unsupported record layout" } */
+struct __attribute__((packed)) S /* { dg-warning "packed layout" } */
{
char c;
int t;
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-24.c b/gcc/testsuite/c-c++-common/gomp/atomic-24.c
new file mode 100644
index 0000000..f70c805
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-24.c
@@ -0,0 +1,12 @@
+/* PR c/101297 */
+
+int i;
+
+void
+foo (void)
+{
+ #pragma omp atomic update, /* { dg-error "expected end of line before ',' token" } */
+ i++;
+ #pragma omp atomic update,, /* { dg-error "expected end of line before ',' token" } */
+ i++;
+}
diff --git a/gcc/testsuite/g++.dg/asan/asan_test.C b/gcc/testsuite/g++.dg/asan/asan_test.C
index c62568f..49933ab 100644
--- a/gcc/testsuite/g++.dg/asan/asan_test.C
+++ b/gcc/testsuite/g++.dg/asan/asan_test.C
@@ -2,7 +2,7 @@
// { dg-skip-if "" { *-*-* } { "*" } { "-O2" } }
// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
// { dg-additional-sources "asan_globals_test-wrapper.cc" }
-// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Werror -Wno-alloc-size-larger-than -Wno-stringop-overflow -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread" }
+// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Werror -Wno-alloc-size-larger-than -Wno-array-bounds -Wno-stringop-overflow -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread" }
// { dg-additional-options "-ldl" { target { ! *-*-freebsd* } } }
// { dg-additional-options "-DASAN_NEEDS_SEGV=1" { target { ! arm*-*-* } } }
// { dg-additional-options "-DASAN_LOW_MEMORY=1 -DASAN_NEEDS_SEGV=0" { target arm*-*-* } }
diff --git a/gcc/testsuite/g++.dg/concepts/explicit-spec1.C b/gcc/testsuite/g++.dg/concepts/explicit-spec1.C
new file mode 100644
index 0000000..d9b6b3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/explicit-spec1.C
@@ -0,0 +1,9 @@
+// PR c++/101098
+// { dg-do compile { target concepts } }
+
+template<typename T> concept C = __is_class(T);
+struct Y { int n; } y;
+template<C T> void g(T) { }
+int called;
+template<> void g(Y) { called = 3; }
+int main() { g(y); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto24.C b/gcc/testsuite/g++.dg/cpp0x/auto24.C
index 193f92e..ac1ba24 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto24.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto24.C
@@ -1,5 +1,6 @@
// PR c++/48599
// { dg-do compile { target c++11 } }
+// Allowed since DR2397.
int v[1];
-auto (*p)[1] = &v; // { dg-error "8:.p. declared as array of .auto" }
+auto (*p)[1] = &v;
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto3.C b/gcc/testsuite/g++.dg/cpp0x/auto3.C
index 2cd0520..7cde745 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
@@ -9,8 +9,8 @@ auto x; // { dg-error "auto" }
// deduction, the program is ill-formed.
auto i = 42, j = 42.0; // { dg-error "auto" }
-// New CWG issue
-auto a[2] = { 1, 2 }; // { dg-error "6:.a. declared as array of .auto" }
+// CWG issue 2397: [dcl.type.auto.deduct]/2: "T shall not be an array type".
+auto a[2] = { 1, 2 }; // { dg-error "20:unable to deduce" }
template<class T>
struct A { };
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto42.C b/gcc/testsuite/g++.dg/cpp0x/auto42.C
index 8d15fc9..5b2f677 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto42.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto42.C
@@ -5,5 +5,5 @@
void foo(int i)
{
- auto x[1] = { 0 }; // { dg-error "8:.x. declared as array of .auto" }
+ auto x[1] = { 0 }; // { dg-error "19:unable to deduce" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C
new file mode 100644
index 0000000..79be244
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C
@@ -0,0 +1,10 @@
+// PR c++/101194
+// { dg-do compile { target c++11 } }
+
+struct nodefault {
+ constexpr nodefault(int) { }
+};
+
+constexpr nodefault x[1] = { nodefault{0} };
+
+constexpr nodefault y = x[0];
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist75.C b/gcc/testsuite/g++.dg/cpp0x/initlist75.C
index 9a45087..f572f51 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist75.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist75.C
@@ -3,4 +3,4 @@
#include <initializer_list>
-auto foo[] = {}; // { dg-error "6:.foo. declared as array of .auto" }
+auto foo[] = {}; // { dg-error "15:unable to deduce" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist80.C b/gcc/testsuite/g++.dg/cpp0x/initlist80.C
index 15723be..a6ab40c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist80.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist80.C
@@ -3,4 +3,4 @@
#include <initializer_list>
-auto x[2] = {}; // { dg-error "6:.x. declared as array of .auto" }
+auto x[2] = {}; // { dg-error "14:unable to deduce" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept70.C b/gcc/testsuite/g++.dg/cpp0x/noexcept70.C
new file mode 100644
index 0000000..45a6137
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept70.C
@@ -0,0 +1,5 @@
+// PR c++/101087
+// { dg-do compile { target c++11 } }
+
+int f();
+static_assert(noexcept(sizeof(f())), "");
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78765.C b/gcc/testsuite/g++.dg/cpp0x/pr78765.C
index 6b66d26..4c63fdd 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr78765.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr78765.C
@@ -8,7 +8,7 @@ struct ValueType {
int field;
};
-static constexpr ValueType var = 0; // { dg-error "conversion" }
+static constexpr ValueType var = 0; // { dg-error "conversion|convert" }
template <int> class ValueTypeInfo;
diff --git a/gcc/testsuite/g++.dg/cpp23/auto-array.C b/gcc/testsuite/g++.dg/cpp23/auto-array.C
new file mode 100644
index 0000000..42f2b0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/auto-array.C
@@ -0,0 +1,36 @@
+// PR c++/100975
+// DR 2397 - auto specifier for pointers and references to arrays
+// { dg-do compile { target c++11 } }
+
+struct false_type { static constexpr bool value = false; };
+struct true_type { static constexpr bool value = true; };
+template<class T, class U>
+struct is_same : false_type {};
+template<class T>
+struct is_same<T, T> : true_type {};
+
+using U = int[3];
+
+void
+g ()
+{
+ int a[3];
+ auto (*p)[3] = &a;
+ auto (&r)[3] = a;
+ int aa[3][3];
+ auto (*pp)[3][3] = &aa;
+ auto (&rr)[3][3] = aa;
+
+ auto (&&rv)[3] = U{};
+
+ static_assert (is_same<decltype (p), int(*)[3]>::value, "");
+ static_assert (is_same<decltype (pp), int(*)[3][3]>::value, "");
+ static_assert (is_same<decltype (r), int(&)[3]>::value, "");
+ static_assert (is_same<decltype (rv), int(&&)[3]>::value, "");
+ static_assert (is_same<decltype (rr), int(&)[3][3]>::value, "");
+
+#if __cplusplus >= 201402L
+ // In a generic lambda parameter this was OK even before.
+ auto l = [](auto (&arr)[5]) { return arr[0]; };
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C
new file mode 100644
index 0000000..8ddcad2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target concepts } }
+
+template<class T> requires T::value struct A { };
+template<class T> requires T::value struct B { }; // { dg-error "private" }
+
+struct S {
+private:
+ static constexpr bool value = true;
+ template<class T> requires T::value friend struct A;
+};
+
+A<S> x;
+B<S> y; // { dg-error "constraint" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C
new file mode 100644
index 0000000..f990ae1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C
@@ -0,0 +1,28 @@
+// PR c++/101247
+// { dg-do compile { target concepts } }
+// A variant of concepts-memtmpl3.C where f is defined outside A's definition.
+
+template <typename> struct A {
+ template <typename c> static constexpr bool d = true;
+ struct B;
+ template <typename> struct C;
+};
+
+template <typename a>
+struct A<a>::B {
+ template <typename c> static void f(c) requires d<c>;
+};
+
+template <typename a>
+template <typename b>
+struct A<a>::C {
+ template <typename c> static void f(c) requires d<c>;
+ static void g() requires d<b>;
+};
+
+int main()
+{
+ A<void>::B::f(0);
+ A<void>::C<int>::f(0);
+ A<void>::C<int>::g();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5.C
new file mode 100644
index 0000000..3c83bb8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5.C
@@ -0,0 +1,11 @@
+// PR c++/101247
+// { dg-do compile { target concepts } }
+
+template<class T, class U> struct A {
+ template<class> static constexpr bool d = true;
+ static void g() requires d<U>;
+};
+
+int main() {
+ A<int, char>::g();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5a.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5a.C
new file mode 100644
index 0000000..458f1cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl5a.C
@@ -0,0 +1,15 @@
+// PR c++/101247
+// { dg-do compile { target concepts } }
+// A variant of concepts-memtmpl5.C that uses a partial specialization
+// of A instead of the primary template.
+
+template<class, class> struct A;
+
+template<class T, class U> requires true struct A<T, U> {
+ template<class V> static constexpr bool d = true;
+ static void g() requires d<U>;
+};
+
+int main() {
+ A<int, char>::g();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires26.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires26.C
new file mode 100644
index 0000000..824d234
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires26.C
@@ -0,0 +1,18 @@
+// PR c++/101181
+// { dg-do compile { target c++20 } }
+
+template<class T,
+ bool = requires { typename T::type; }>
+struct p { using type = void; };
+
+template<class T>
+struct p<T, true> { using type = typename T::type; };
+
+template<class T> using P = typename p<T>::type;
+
+using type1 = P<int>;
+using type1 = void;
+
+struct A { using type = char; };
+using type2 = P<A>;
+using type2 = char;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires27.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires27.C
new file mode 100644
index 0000000..99d4500
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires27.C
@@ -0,0 +1,10 @@
+// PR c++/82110
+// { dg-do compile { target c++20 } }
+
+struct X { X() = delete; };
+
+template<class T> concept C = requires(T t) { new T; };
+template<class T> concept D = requires(T t) { new T[1]; };
+
+static_assert(!C<X>);
+static_assert(!D<X>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval16.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval16.C
new file mode 100644
index 0000000..1113c6f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval16.C
@@ -0,0 +1,22 @@
+// PR c++/101181
+// { dg-do compile { target c++20 } }
+
+template<class T,
+ bool = [] () -> bool {
+ if constexpr (requires { typename T::type; })
+ return true;
+ return false;
+ }()>
+struct p { using type = void; };
+
+template<class T>
+struct p<T, true> { using type = typename T::type; };
+
+template<class T> using P = typename p<T>::type;
+
+using type1 = P<int>;
+using type = void;
+
+struct A { using type = char; };
+using type2 = P<A>;
+using type2 = char;
diff --git a/gcc/testsuite/g++.dg/diagnostic/auto1.C b/gcc/testsuite/g++.dg/diagnostic/auto1.C
index ee2eefd..9d9979e 100644
--- a/gcc/testsuite/g++.dg/diagnostic/auto1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/auto1.C
@@ -1,4 +1,5 @@
// PR c++/86915
// { dg-do compile { target c++17 } }
+// Allowed since DR2397.
-template<auto [1]> struct S; // { dg-error "creating array of .auto." }
+template<auto [1]> struct S;
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-1.C b/gcc/testsuite/g++.dg/gomp/attrs-1.C
new file mode 100644
index 0000000..c2734a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C
@@ -0,0 +1,553 @@
+// { dg-do compile { target c++11 } }
+
+typedef enum omp_allocator_handle_t
+: __UINTPTR_TYPE__
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+typedef enum omp_sync_hint_t {
+omp_sync_hint_none = 0x0,
+omp_lock_hint_none = omp_sync_hint_none,
+omp_sync_hint_uncontended = 0x1,
+omp_lock_hint_uncontended = omp_sync_hint_uncontended,
+omp_sync_hint_contended = 0x2,
+omp_lock_hint_contended = omp_sync_hint_contended,
+omp_sync_hint_nonspeculative = 0x4,
+omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative,
+omp_sync_hint_speculative = 0x8,
+omp_lock_hint_speculative = omp_sync_hint_speculative
+} omp_sync_hint_t;
+
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t {
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+int t;
+#pragma omp threadprivate (t)
+
+#pragma omp declare target
+int f, l, ll, r, r2;
+
+void
+foo (int d, int m, int i1, int i2, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
+{
+ [[omp::directive (distribute parallel for
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) order(concurrent) allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute parallel for simd
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) nontemporal(ntm)
+ safelen(8) simdlen(4) aligned(q: 32) order(concurrent) allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute simd
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
+ order(concurrent) allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+}
+
+void
+qux (int p)
+{
+ [[omp::directive (loop bind(teams) order(concurrent)
+ private (p) lastprivate (l) collapse(1) reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+}
+#pragma omp end declare target
+
+void
+baz (int d, int m, int i1, int i2, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
+{
+ [[omp::directive (distribute parallel for
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) copyin(t) order(concurrent) allocate (p))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute parallel for simd
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) nontemporal(ntm)
+ safelen(8) simdlen(4) aligned(q: 32) copyin(t) order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute simd
+ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16)
+ safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
+ order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (loop bind(parallel) order(concurrent)
+ private (p) lastprivate (l) collapse(1) reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+}
+
+void
+bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm)
+{
+ [[omp::directive (for simd
+ private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait
+ safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1) order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (for
+ private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait
+ order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (simd
+ private (p) lastprivate (l) linear (ll:1) reduction(+:r) collapse(1) safelen(8) simdlen(4) aligned(q: 32)
+ nontemporal(ntm) if(i1) order(concurrent))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for simd
+ private (p) firstprivate (f) if (i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1)
+ safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel sections
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) allocate (f))]]
+ {
+ #pragma omp section
+ {}
+ #pragma omp section
+ {}
+ }
+ [[omp::directive (sections private (p) firstprivate (f) reduction(+:r) lastprivate (l) allocate (f) nowait)]]
+ {
+ ;
+ #pragma omp section
+ ;
+ #pragma omp section
+ {}
+ }
+ [[omp::directive (barrier)]];
+ [[omp::sequence (omp::directive (single private (p) firstprivate (f) allocate (f) nowait))]]
+ ;
+ [[omp::sequence (directive (barrier))]];
+ [[omp::sequence (directive (parallel private (p)),
+ omp::directive (single copyprivate (p) firstprivate (f) allocate (f)))]]
+ p = 6;
+ [[omp::directive (target parallel
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ nowait depend(inout: dd[0]) allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ ;
+ [[omp::directive (target parallel for
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1) nowait depend(inout: dd[0])
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target parallel for
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) nowait depend(inout: dd[0]) order(concurrent)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (omp::directive (target parallel for simd
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1)
+ safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3) order(concurrent)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (target teams
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0])
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
+ ;
+ [[omp::sequence (directive (target
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ nowait depend(inout: dd[0]) allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
+ ;
+ [[omp::sequence (omp::directive (target teams distribute
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) nowait depend(inout: dd[0]) allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ;
+ [[omp::directive (target teams distribute parallel for
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0]) order(concurrent)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target teams distribute parallel for simd
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target teams distribute simd
+ device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target simd
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r)
+ nowait depend(inout: dd[0]) nontemporal(ntm) if(simd:i3) order(concurrent)
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup task_reduction(+:r2) allocate (r2)),
+ omp::directive (taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ order(concurrent) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (omp::directive (taskgroup task_reduction(+:r) allocate (r)),
+ directive (taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(i1) final(fi) mergeable nogroup priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm)
+ order(concurrent) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (taskwait)]];
+ [[omp::directive (taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) if(taskloop: i1) final(fi) priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm)
+ order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup task_reduction(+:r2) allocate (r2)),
+ omp::directive (taskloop
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
+ reduction(default, +:r) in_reduction(+:r2) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup task_reduction(+:r2) allocate (r2)),
+ omp::directive (task
+ private (p) firstprivate (f) shared (s) default(shared) untied if(task: i1) final(fi) mergeable priority (pp)
+ in_reduction(+:r2) allocate (f)))]]
+ ;
+ [[omp::directive (taskyield)]];
+ [[omp::directive (target data if (target data: i1) device(d) map (tofrom: m) use_device_ptr (q) use_device_addr (p))]]
+ ;
+ [[omp::directive (target enter data if (target enter data: i1) device(d) map (to: m) depend(inout: dd[0]) nowait)]]
+ ;
+ [[omp::directive (target exit data if (target exit data: i1) device(d) map (from: m) depend(inout: dd[0]) nowait)]]
+ ;
+ [[omp::directive (target update if (target update: i1) device(d) to (m) depend(inout: dd[0]) nowait)]]
+ ;
+ [[omp::directive (target update if (target update: i1) device(d) from (m) depend(inout: dd[0]) nowait)]]
+ ;
+ [[omp::directive (taskwait)]];
+ [[omp::sequence (directive (target nowait depend(inout: dd[0]) in_reduction(+:r2)),
+ directive (teams distribute
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ;
+ [[omp::directive (teams
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ allocate (omp_default_mem_alloc: f))]]
+ ;
+ [[omp::sequence (omp::directive (target),
+ omp::directive (teams distribute parallel for
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) order(concurrent) allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (target),
+ directive (teams distribute parallel for simd
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm)
+ allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (target),
+ directive (teams distribute simd
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm)
+ allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute parallel for
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) order(concurrent)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) copyin(t) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute parallel for simd
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16)
+ if (parallel: i2) num_threads (nth) proc_bind(spread)
+ lastprivate (l) schedule(static, 4) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm) copyin(t)
+ allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute simd
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) dist_schedule(static, 16) order(concurrent)
+ safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm) allocate(f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r)
+ num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
+ ;
+ [[omp::directive (parallel
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r)
+ num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
+ ;
+ [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)),
+ omp::directive (master taskloop
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
+ reduction(default, +:r) in_reduction(+:r2) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (master)]];
+ [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
+ directive (master taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ order(concurrent) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
+ reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
+ order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)),
+ directive (master taskloop
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+ reduction(default, +:r) in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
+ omp::directive (master taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ order(concurrent) allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+ reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop simd
+ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t)
+ order(concurrent) allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (loop bind(thread) order(concurrent)
+ private (p) lastprivate (l) collapse(1) reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+ [[omp::directive (parallel loop
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) collapse(1) bind(parallel) order(concurrent) allocate (f))]]
+ for (l = 0; l < 64; l++)
+ ll++;
+ [[omp::directive (parallel loop
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread)
+ lastprivate (l) collapse(1) allocate (f))]]
+ for (l = 0; l < 64; l++)
+ ll++;
+ [[omp::directive (teams loop
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) lastprivate (l) bind(teams) allocate (f))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (teams loop
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+ collapse(1) lastprivate (l) order(concurrent) allocate (f))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target parallel loop
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ nowait depend(inout: dd[0]) lastprivate (l) bind(parallel) order(concurrent) collapse(1)
+ allocate (omp_default_mem_alloc: f) in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target parallel loop
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread)
+ nowait depend(inout: dd[0]) lastprivate (l) order(concurrent) collapse(1)
+ allocate (omp_default_mem_alloc: f) in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target teams loop
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0])
+ lastprivate (l) bind(teams) collapse(1)
+ allocate (omp_default_mem_alloc: f) in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target teams loop
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0])
+ lastprivate (l) order(concurrent) collapse(1)
+ allocate (omp_default_mem_alloc: f) in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (critical)]] {
+ }
+ [[omp::directive (critical (foobar) hint(omp_sync_hint_none))]]
+ ;
+ [[omp::directive (taskwait depend (inout: dd[0]))]]
+ ;
+ [[omp::directive (taskgroup task_reduction(+:r2) allocate (r2))]]
+ ;
+ [[omp::directive (atomic update seq_cst hint(omp_sync_hint_none))]]
+ p++;
+ [[omp::directive (atomic read hint(omp_sync_hint_none) relaxed)]]
+ f = p;
+ [[omp::directive (atomic write release hint(omp_sync_hint_none))]]
+ p = f;
+ [[omp::directive (flush)]]
+ ;
+ [[omp::directive (flush acq_rel)]]
+ ;
+ [[omp::directive (flush (p, f))]]
+ ;
+ [[omp::directive (simd
+ private (p) lastprivate (l) linear (ll:1) reduction(+:r) collapse(1) safelen(8) simdlen(4) aligned(q: 32)
+ nontemporal(ntm) if(i1))]]
+ for (int i = 0; i < 64; i++)
+ [[omp::directive (ordered simd)]]
+ ll++;
+ [[omp::directive (for
+ private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait
+ ordered allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ [[omp::directive (ordered threads)]]
+ ll++;
+ [[omp::directive(for ordered (1))]]
+ for (l = 0; l < 64; l++)
+ {
+ [[omp::directive(ordered depend (sink: l - 1))]];
+ [[omp::directive(ordered depend (source))]];
+ }
+ extern omp_depend_t depobj;
+ [[omp::directive (depobj(depobj) depend(in : dd[0]))]];
+ [[omp::directive (parallel)]] {
+ if (p) {
+ [[omp::directive (cancel parallel)]];
+ } else {
+ [[omp::directive (cancellation point parallel)]];
+ }
+ }
+ extern int t2;
+ [[omp::directive (threadprivate (t2))]]
+ extern int t2;
+ [[omp::directive (declare reduction (dr: int: omp_out += omp_in) initializer (omp_priv = 0))]]
+ ;
+}
+
+void corge1 ();
+
+void
+corge ()
+{
+ [[omp::directive (declare variant (corge1) match (construct={parallel,for}))]]
+ extern void corge2 ();
+ [[omp::sequence (directive (parallel), directive (for))]]
+ for (int i = 0; i < 5; i++)
+ corge2 ();
+ [[omp::directive (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch),
+ omp::directive (declare simd simdlen(8) notinbranch)]]
+ extern int corge3 (int l, int *p);
+ [[omp::directive (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch),
+ directive (declare simd simdlen(8) notinbranch)]]
+ extern int corge4 (int l, int *p);
+ [[omp::sequence (directive (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch),
+ omp::directive (declare simd simdlen(8) notinbranch))]]
+ extern int corge5 (int l, int *p);
+ [[omp::directive (declare target)]];
+ extern void corge6 ();
+ [[omp::directive (end declare target)]];
+}
+
+int
+garply (int a, int *c, int *d, int *e, int *f)
+{
+ int i;
+ [[omp::directive (simd reduction (inscan, +: a))]]
+ for (i = 0; i < 64; i++)
+ {
+ d[i] = a;
+ #pragma omp scan exclusive (a)
+ a += c[i];
+ }
+ [[omp::directive (simd reduction (inscan, +: a))]]
+ for (i = 0; i < 64; i++)
+ {
+ a += c[i];
+ #pragma omp scan inclusive (a)
+ d[i] = a;
+ }
+ return a;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-2.C b/gcc/testsuite/g++.dg/gomp/attrs-2.C
new file mode 100644
index 0000000..1eb6263
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-2.C
@@ -0,0 +1,553 @@
+// { dg-do compile { target c++17 } }
+
+typedef enum omp_allocator_handle_t
+: __UINTPTR_TYPE__
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+typedef enum omp_sync_hint_t {
+omp_sync_hint_none = 0x0,
+omp_lock_hint_none = omp_sync_hint_none,
+omp_sync_hint_uncontended = 0x1,
+omp_lock_hint_uncontended = omp_sync_hint_uncontended,
+omp_sync_hint_contended = 0x2,
+omp_lock_hint_contended = omp_sync_hint_contended,
+omp_sync_hint_nonspeculative = 0x4,
+omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative,
+omp_sync_hint_speculative = 0x8,
+omp_lock_hint_speculative = omp_sync_hint_speculative
+} omp_sync_hint_t;
+
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t {
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+int t;
+#pragma omp threadprivate (t)
+
+#pragma omp declare target
+int f, l, ll, r, r2;
+
+void
+foo (int d, int m, int i1, int i2, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
+{
+ [[omp::directive (distribute parallel for,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),order(concurrent),allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute parallel for simd,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),if(simd: i1),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),nontemporal(ntm),
+ safelen(8),simdlen(4),aligned(q: 32),order(concurrent),allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute simd,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ safelen(8),simdlen(4),aligned(q: 32),reduction(+:r),if(i1),nontemporal(ntm),
+ order(concurrent),allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ allocate (omp_default_mem_alloc:f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+}
+
+void
+qux (int p)
+{
+ [[omp::directive (loop, bind(teams),order(concurrent),
+ private (p),lastprivate (l),collapse(1),reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+}
+#pragma omp end declare target
+
+void
+baz (int d, int m, int i1, int i2, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
+{
+ [[omp::directive (distribute parallel for,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),copyin(t),order(concurrent),allocate (p))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute parallel for simd,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),if(simd: i1),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),nontemporal(ntm),
+ safelen(8),simdlen(4),aligned(q: 32),copyin(t),order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (distribute simd,
+ private (p),firstprivate (f),collapse(1),dist_schedule(static, 16),
+ safelen(8),simdlen(4),aligned(q: 32),reduction(+:r),if(i1),nontemporal(ntm),
+ order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (loop, bind(parallel),order(concurrent),
+ private (p),lastprivate (l),collapse(1),reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+}
+
+void
+bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
+ int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm)
+{
+ [[omp::directive (for simd,
+ private (p),firstprivate (f),lastprivate (l),linear (ll:1),reduction(+:r),schedule(static, 4),collapse(1),nowait,
+ safelen(8),simdlen(4),aligned(q: 32),nontemporal(ntm),if(i1),order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (for,
+ private (p),firstprivate (f),lastprivate (l),linear (ll:1),reduction(+:r),schedule(static, 4),collapse(1),nowait,
+ order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (simd,
+ private (p),lastprivate (l),linear (ll:1),reduction(+:r),collapse(1),safelen(8),simdlen(4),aligned(q: 32),
+ nontemporal(ntm),if(i1),order(concurrent))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),ordered schedule(static, 4),collapse(1),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),schedule(static, 4),collapse(1),order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel for simd,
+ private (p),firstprivate (f),if (i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),schedule(static, 4),collapse(1),
+ safelen(8),simdlen(4),aligned(q: 32),nontemporal(ntm),order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel sections,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),allocate (f))]]
+ {
+ #pragma omp section
+ {}
+ #pragma omp section
+ {}
+ }
+ [[omp::directive (sections, private (p),firstprivate (f),reduction(+:r),lastprivate (l),allocate (f),nowait)]]
+ {
+ ;
+ #pragma omp section
+ ;
+ #pragma omp section
+ {}
+ }
+ [[omp::directive (barrier)]];
+ [[using omp:sequence (omp::directive (single, private (p),firstprivate (f),allocate (f),nowait))]]
+ ;
+ [[omp::sequence (directive (barrier))]];
+ [[using omp:sequence (directive (parallel, private (p)),
+ omp::directive (single, copyprivate (p),firstprivate (f),allocate (f)))]]
+ p = 6;
+ [[omp::directive (target parallel,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread)
+ nowait depend(inout: dd[0]),allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ ;
+ [[omp::directive (target parallel for,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),ordered schedule(static, 4),collapse(1),nowait depend(inout: dd[0]),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[using omp:directive (target parallel for,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),schedule(static, 4),collapse(1),nowait depend(inout: dd[0]),order(concurrent),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (omp::directive (target parallel for simd,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),linear (ll:1),schedule(static, 4),collapse(1),
+ safelen(8),simdlen(4),aligned(q: 32),nowait depend(inout: dd[0]),nontemporal(ntm),if (simd: i3),order(concurrent),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[using omp:sequence (directive (target teams,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),nowait, depend(inout: dd[0]),
+ allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
+ ;
+ [[using omp:sequence (directive (target,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ nowait depend(inout: dd[0]),allocate (omp_default_mem_alloc:f),in_reduction(+:r2)))]]
+ ;
+ [[omp::sequence (omp::directive (target teams distribute,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),nowait depend(inout: dd[0]),allocate (omp_default_mem_alloc:f),in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ;
+ [[omp::directive (target teams distribute parallel for,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),nowait depend(inout: dd[0]),order(concurrent),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target teams distribute parallel for simd,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),nowait depend(inout: dd[0]),nontemporal(ntm),if (simd: i3),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target teams distribute simd,
+ device(d),map (tofrom: m),if (i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),nowait depend(inout: dd[0]),nontemporal(ntm),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (target simd,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ safelen(8),simdlen(4),lastprivate (l),linear(ll: 1),aligned(q: 32),reduction(+:r),
+ nowait depend(inout: dd[0]),nontemporal(ntm),if(simd:i3),order(concurrent),
+ allocate (omp_default_mem_alloc:f),in_reduction(+:r2))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup, task_reduction(+:r2), allocate (r2)),
+ omp::directive (taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),in_reduction(+:r2),nontemporal(ntm),
+ order(concurrent),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[using omp:sequence (omp::directive (taskgroup, task_reduction(+:r), allocate (r)),
+ directive (taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(i1),final(fi),mergeable,nogroup,priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),in_reduction(+:r),nontemporal(ntm),
+ order(concurrent),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (taskwait)]];
+ [[omp::directive (taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),if(taskloop: i1),final(fi),priority (pp)
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(+:r),if (simd: i3),nontemporal(ntm),
+ order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup, task_reduction(+:r2), allocate (r2)),
+ omp::directive (taskloop
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied, if(taskloop: i1),final(fi),mergeable, priority (pp),
+ reduction(default, +:r),in_reduction(+:r2),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup, task_reduction(+:r2),allocate (r2)),
+ omp::directive (task,
+ private (p),firstprivate (f),shared (s),default(shared),untied,if(task: i1),final(fi),mergeable,priority (pp),
+ in_reduction(+:r2),allocate (f)))]]
+ ;
+ [[omp::directive (taskyield)]];
+ [[omp::directive (target data, if (target data: i1),device(d),map (tofrom: m),use_device_ptr (q),use_device_addr (p))]]
+ ;
+ [[omp::directive (target enter data, if (target enter data: i1),device(d),map (to: m),depend(inout: dd[0]),nowait)]]
+ ;
+ [[omp::directive (target exit data, if (target exit data: i1),device(d),map (from: m),depend(inout: dd[0]),nowait)]]
+ ;
+ [[omp::directive (target update, if (target update: i1),device(d),to (m),depend(inout: dd[0]),nowait)]]
+ ;
+ [[omp::directive (target update, if (target update: i1),device(d),from (m),depend(inout: dd[0]),nowait)]]
+ ;
+ [[omp::directive (taskwait)]];
+ [[omp::sequence (directive (target, nowait,depend(inout: dd[0]),in_reduction(+:r2)),
+ directive (teams distribute,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ;
+ [[omp::directive (teams,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ allocate (omp_default_mem_alloc: f))]]
+ ;
+ [[omp::sequence (omp::directive (target),
+ omp::directive (teams distribute parallel for,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),order(concurrent),allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[using omp:sequence (directive (target),
+ directive (teams distribute parallel for simd,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),if (simd: i3),nontemporal(ntm),
+ allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (target),
+ directive (teams distribute simd,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),if(i3),nontemporal(ntm),
+ allocate (omp_default_mem_alloc: f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute parallel for,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),order(concurrent),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),copyin(t),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute parallel for simd,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),
+ if (parallel: i2),num_threads (nth),proc_bind(spread),
+ lastprivate (l),schedule(static, 4),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),if (simd: i3),nontemporal(ntm),copyin(t),
+ allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (teams distribute simd,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),dist_schedule(static, 16),order(concurrent),
+ safelen(8),simdlen(4),aligned(q: 32),if(i3),nontemporal(ntm),allocate(f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r),
+ num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
+ ;
+ [[omp::directive (parallel,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r),
+ num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
+ ;
+ [[using omp:sequence (directive (taskgroup, task_reduction (+:r2),allocate (r2)),
+ omp::directive (master taskloop,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied, if(taskloop: i1),final(fi),mergeable, priority (pp),
+ reduction(default, +:r),in_reduction(+:r2),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[using omp:directive (master)]];
+ [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2),allocate (r2)),
+ directive (master taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),in_reduction(+:r2),nontemporal(ntm),
+ order(concurrent),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),final(fi),mergeable,priority (pp),
+ reduction(default, +:r),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),
+ order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (directive (taskgroup,task_reduction (+:r2),allocate (r2)),
+ directive (master taskloop,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
+ reduction(default, +:r),in_reduction(+:r2)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::sequence (omp::directive (taskgroup,task_reduction (+:r2),allocate (r2)),
+ omp::directive (master taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),in_reduction(+:r2),nontemporal(ntm),
+ order(concurrent),allocate (f)))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
+ reduction(default, +:r),num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (parallel master taskloop simd,
+ private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
+ safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),num_threads (nth),proc_bind(spread),copyin(t),
+ order(concurrent),allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ ll++;
+ [[omp::directive (loop, bind(thread),order(concurrent),
+ private (p),lastprivate (l),collapse(1),reduction(+:r))]]
+ for (l = 0; l < 64; ++l)
+ ll++;
+ [[omp::directive (parallel loop,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),collapse(1),bind(parallel),order(concurrent),allocate (f))]]
+ for (l = 0; l < 64; l++)
+ ll++;
+ [[omp::directive (parallel loop,
+ private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),copyin(t),reduction(+:r),num_threads (nth),proc_bind(spread),
+ lastprivate (l),collapse(1),allocate (f))]]
+ for (l = 0; l < 64; l++)
+ ll++;
+ [[omp::directive (teams loop,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),lastprivate (l),bind(teams),allocate (f))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (teams loop,
+ private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+ collapse(1),lastprivate (l),order(concurrent),allocate (f))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target parallel loop,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ nowait depend(inout: dd[0]),lastprivate (l),bind(parallel),order(concurrent),collapse(1),
+ allocate (omp_default_mem_alloc: f),in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target parallel loop,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ if (parallel: i2),default(shared),shared(s),reduction(+:r),num_threads (nth),proc_bind(spread),
+ nowait depend(inout: dd[0]),lastprivate (l),order(concurrent),collapse(1),
+ allocate (omp_default_mem_alloc: f),in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target teams loop,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),nowait,depend(inout: dd[0]),
+ lastprivate (l),bind(teams),collapse(1),
+ allocate (omp_default_mem_alloc: f),in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (target teams loop,
+ device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
+ shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),nowait,depend(inout: dd[0]),
+ lastprivate (l),order(concurrent),collapse(1)
+ allocate (omp_default_mem_alloc: f),in_reduction(+:r2))]]
+ for (l = 0; l < 64; ++l)
+ ;
+ [[omp::directive (critical)]] {
+ }
+ [[omp::directive (critical (foobar),hint(omp_sync_hint_none))]]
+ ;
+ [[using omp:directive (taskwait, depend (inout: dd[0]))]]
+ ;
+ [[omp::directive (taskgroup, task_reduction(+:r2),allocate (r2))]]
+ ;
+ [[omp::directive (atomic, update,seq_cst,hint(omp_sync_hint_none))]]
+ p++;
+ [[omp::directive (atomic, read, hint(omp_sync_hint_none),relaxed)]]
+ f = p;
+ [[omp::directive (atomic,write, release hint(omp_sync_hint_none))]]
+ p = f;
+ [[omp::directive (flush)]]
+ ;
+ [[omp::directive (flush, acq_rel)]]
+ ;
+ [[omp::directive (flush (p, f))]]
+ ;
+ [[omp::directive (simd,
+ private (p),lastprivate (l),linear (ll:1),reduction(+:r),collapse(1),safelen(8),simdlen(4),aligned(q: 32),
+ nontemporal(ntm),if(i1))]]
+ for (int i = 0; i < 64; i++)
+ [[omp::directive (ordered, simd)]]
+ ll++;
+ [[omp::directive (for,
+ private (p),firstprivate (f),lastprivate (l),linear (ll:1),reduction(+:r),schedule(static, 4),collapse(1),nowait,
+ ordered, allocate (f))]]
+ for (int i = 0; i < 64; i++)
+ [[omp::directive (ordered, threads)]]
+ ll++;
+ [[omp::directive(for, ordered (1))]]
+ for (l = 0; l < 64; l++)
+ {
+ [[omp::directive(ordered, depend (sink: l - 1))]];
+ [[omp::directive(ordered, depend (source))]];
+ }
+ extern omp_depend_t depobj;
+ [[omp::directive (depobj(depobj),depend(in : dd[0]))]];
+ [[omp::directive (parallel)]] {
+ if (p) {
+ [[omp::directive (cancel, parallel)]];
+ } else {
+ [[omp::directive (cancellation point, parallel)]];
+ }
+ }
+ extern int t2;
+ [[omp::directive (threadprivate (t2))]]
+ extern int t2;
+ [[omp::directive (declare reduction (dr: int: omp_out += omp_in),initializer (omp_priv = 0))]]
+ ;
+}
+
+void corge1 ();
+
+void
+corge ()
+{
+ [[omp::directive (declare variant (corge1),match (construct={parallel,for}))]]
+ extern void corge2 ();
+ [[omp::sequence (directive (parallel), directive (for))]]
+ for (int i = 0; i < 5; i++)
+ corge2 ();
+ [[omp::directive (declare simd, simdlen(4),linear(l),aligned(p:4),uniform(p),inbranch),
+ omp::directive (declare simd,simdlen(8),notinbranch)]]
+ extern int corge3 (int l, int *p);
+ [[using omp:directive (declare simd, simdlen(4),linear(l),aligned(p:4),uniform(p),inbranch),
+ directive (declare simd, simdlen(8),notinbranch)]]
+ extern int corge4 (int l, int *p);
+ [[omp::sequence (directive (declare simd, simdlen(4),linear(l),aligned(p:4),uniform(p),inbranch),
+ omp::directive (declare simd, simdlen(8),notinbranch))]]
+ extern int corge5 (int l, int *p);
+ [[omp::directive (declare target)]];
+ extern void corge6 ();
+ [[omp::directive (end declare target)]];
+}
+
+int
+garply (int a, int *c, int *d, int *e, int *f)
+{
+ int i;
+ [[omp::directive (simd, reduction (inscan, +: a))]]
+ for (i = 0; i < 64; i++)
+ {
+ d[i] = a;
+ #pragma omp scan exclusive (a)
+ a += c[i];
+ }
+ [[omp::directive (simd, reduction (inscan, +: a))]]
+ for (i = 0; i < 64; i++)
+ {
+ a += c[i];
+ #pragma omp scan inclusive (a)
+ d[i] = a;
+ }
+ return a;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-3.C b/gcc/testsuite/g++.dg/gomp/attrs-3.C
new file mode 100644
index 0000000..7aab637
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-3.C
@@ -0,0 +1,40 @@
+// { dg-do compile { target c++11 } }
+
+int i;
+int t1, t2, t3, t4, t5, t6, t7;
+
+void
+foo ()
+{
+ [[omp::directive]]; // { dg-error "'omp::directive' attribute requires argument" }
+ [[omp::directive ()]]; // { dg-error "expected OpenMP directive name" }
+ [[omp::directive (nonexistent foobar)]]; // { dg-error "unknown OpenMP directive name in 'omp::directive' attribute argument" }
+ [[omp::sequence]]; // { dg-error "'omp::sequence' attribute requires argument" }
+ [[omp::sequence()]]; // { dg-error "expected 'directive' or 'sequence'" }
+ [[omp::sequence(foobar())]]; // { dg-error "expected 'directive' or 'sequence'" }
+ [[omp::sequence(omp::foobar())]]; // { dg-error "expected 'directive' or 'sequence'" }
+ [[omp::sequence(directive(taskwait), foobar())]]; // { dg-error "expected 'directive' or 'sequence'" }
+ [[omp::sequence(omp::directive(taskwait), omp::foobar())]]; // { dg-error "expected 'directive' or 'sequence'" }
+ [[omp::sequence(directive(taskwait) foobar())]]; // { dg-error "expected '\\\)' before 'foobar'" }
+ [[omp::sequence(directive)]]; // { dg-error "expected '\\\(' before '\\\)' token" }
+ [[omp::sequence(omp::sequence)]]; // { dg-error "expected '\\\(' before '\\\)' token" }
+ [[omp::directive (parallel), omp::directive (single)]] // { dg-error "OpenMP construct among 'omp::directive' attributes requires all 'omp::directive' attributes on the same statement to be in the same 'omp::sequence'" }
+ ;
+ [[omp::directive (parallel)]] // { dg-error "OpenMP construct among 'omp::directive' attributes requires all 'omp::directive' attributes on the same statement to be in the same 'omp::sequence'" }
+ [[omp::directive (single)]]
+ ;
+ [[omp::directive (taskwait), omp::directive (taskyield)]] // { dg-error "multiple OpenMP standalone directives among 'omp::directive' attributes must be all within the same 'omp::sequence'" }
+ ;
+ [[omp::directive (taskwait)]]
+ [[omp::directive (taskyield)]] // { dg-error "multiple OpenMP standalone directives among 'omp::directive' attributes must be all within the same 'omp::sequence'" }
+ ;
+ [[omp::directive (flush)]] // { dg-error "standalone OpenMP directives in 'omp::directive' attribute can only appear on an empty statement" }
+ i++;
+ auto a = [] () [[omp::directive (threadprivate (t1))]] {}; // { dg-error "'omp::directive' not allowed to be specified in this context" }
+ int [[omp::directive (threadprivate (t2))]] b; // { dg-warning "attribute ignored" }
+ int *[[omp::directive (threadprivate (t3))]] c; // { dg-warning "'omp::directive' scoped attribute directive ignored" }
+ int &[[omp::directive (threadprivate (t4))]] d = b; // { dg-warning "'omp::directive' scoped attribute directive ignored" }
+ typedef int T [[omp::directive (threadprivate (t5))]]; // { dg-error "'omp::directive' not allowed to be specified in this context" }
+ int e[10] [[omp::directive (threadprivate (t6))]]; // { dg-error "'omp::directive' not allowed to be specified in this context" }
+ struct [[omp::directive (threadprivate (t7))]] S {}; // { dg-error "'omp::directive' not allowed to be specified in this context" }
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr99728.C b/gcc/testsuite/g++.dg/opt/pr99728.C
new file mode 100644
index 0000000..d439323
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr99728.C
@@ -0,0 +1,50 @@
+// PR/99728
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-lim2-details -w -Wno-psabi" }
+
+typedef double __m256d __attribute__((vector_size(sizeof (double) * 4)));
+extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_set1_pd (double __A)
+{
+ return __extension__ (__m256d){ __A, __A, __A, __A };
+}
+
+// simple OO wrapper around __m256d
+struct Tvsimple
+ {
+ __m256d v;
+ Tvsimple &operator+=(const Tvsimple &other) {v+=other.v; return *this;}
+ Tvsimple operator*(double val) const { Tvsimple res; res.v = v*_mm256_set1_pd(val); return res;}
+ Tvsimple operator*(Tvsimple val) const { Tvsimple res; res.v = v*val.v; return res; }
+ Tvsimple operator+(Tvsimple val) const { Tvsimple res; res.v = v+val.v; return res; }
+ Tvsimple operator+(double val) const { Tvsimple res; res.v = v+_mm256_set1_pd(val); return res;}
+ };
+
+template<typename vtype> struct s0data_s
+ { vtype sth, corfac, scale, lam1, lam2, csq, p1r, p1i, p2r, p2i; };
+
+template<typename vtype> void foo(s0data_s<vtype> & __restrict__ d,
+ const double * __restrict__ coef, const double * __restrict__ alm,
+ unsigned long l, unsigned long il, unsigned long lmax)
+ {
+// critical loop
+ while (l<=lmax)
+ {
+ d.p1r += d.lam2*alm[2*l];
+ d.p1i += d.lam2*alm[2*l+1];
+ d.p2r += d.lam2*alm[2*l+2];
+ d.p2i += d.lam2*alm[2*l+3];
+ Tvsimple tmp = d.lam2*(d.csq*coef[2*il] + coef[2*il+1]) + d.lam1;
+ d.lam1 = d.lam2;
+ d.lam2 = tmp;
+ ++il; l+=2;
+ }
+ }
+
+// this version has dead stores at the end of the loop
+template void foo<>(s0data_s<Tvsimple> & __restrict__ d,
+ const double * __restrict__ coef, const double * __restrict__ alm,
+ unsigned long l, unsigned long il, unsigned long lmax);
+
+// The aggregate copy in the IL should not prevent all store-motion
+// { dg-final { scan-tree-dump-times "Executing store motion" 4 "lim2" } }
diff --git a/gcc/testsuite/g++.dg/pr95768.C b/gcc/testsuite/g++.dg/pr95768.C
index 5e2c8c4..d34d513 100644
--- a/gcc/testsuite/g++.dg/pr95768.C
+++ b/gcc/testsuite/g++.dg/pr95768.C
@@ -1,6 +1,6 @@
/* PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
extern "C" void *malloc (__SIZE_TYPE__);
diff --git a/gcc/testsuite/g++.dg/template/access41.C b/gcc/testsuite/g++.dg/template/access41.C
new file mode 100644
index 0000000..1ab9a1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/access41.C
@@ -0,0 +1,24 @@
+// PR c++/96204
+// { dg-do compile { target c++14 } }
+// A variant of access40.C where has_type_member is a variable template instead
+// of a class template.
+
+template<class, class = void>
+constexpr bool has_type_member = false;
+
+template<class T>
+constexpr bool has_type_member<T, typename T::type> = true;
+
+struct Parent;
+
+struct Child {
+private:
+ friend struct Parent;
+ typedef void type;
+};
+
+struct Parent {
+ // The partial specialization does not match despite Child::type
+ // being accessible from the current scope.
+ static_assert(!has_type_member<Child>, "");
+};
diff --git a/gcc/testsuite/g++.dg/template/access41a.C b/gcc/testsuite/g++.dg/template/access41a.C
new file mode 100644
index 0000000..e108049
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/access41a.C
@@ -0,0 +1,29 @@
+// PR c++/96204
+// { dg-do compile { target c++14 } }
+// A variant of access40a.C where has_type_member is a variable template instead
+// of a class template.
+
+template<class T>
+struct A {
+ template<class, class = void>
+ static constexpr bool has_type_member = false;
+};
+
+template<class T>
+template<class U>
+constexpr int A<T>::has_type_member<U, typename U::type> = true;
+
+struct Child {
+private:
+ friend struct A<int>;
+ typedef void type;
+};
+
+// The partial specialization matches because A<int> is a friend of Child.
+static_assert(A<int>::has_type_member<Child>, "");
+using type1 = const int;
+using type1 = decltype(A<int>::has_type_member<Child>);
+
+static_assert(!A<char>::has_type_member<Child>, "");
+using type2 = const bool;
+using type2 = decltype(A<char>::has_type_member<Child>);
diff --git a/gcc/testsuite/g++.dg/template/sfinae14.C b/gcc/testsuite/g++.dg/template/sfinae14.C
index 93eba43a..0c59dad 100644
--- a/gcc/testsuite/g++.dg/template/sfinae14.C
+++ b/gcc/testsuite/g++.dg/template/sfinae14.C
@@ -76,4 +76,4 @@ STATIC_ASSERT(!(has_new_one_arg<X, int X::*>::value));
STATIC_ASSERT((has_array_new<Y, int, 5>::value));
STATIC_ASSERT(!(has_array_new<X, int Y::*, &Y::foo>::value));
-STATIC_ASSERT((has_array_new<X, int, 5>::value));
+STATIC_ASSERT(!(has_array_new<X, int, 5>::value));
diff --git a/gcc/testsuite/g++.dg/torture/pr101256.C b/gcc/testsuite/g++.dg/torture/pr101256.C
new file mode 100644
index 0000000..973a8b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr101256.C
@@ -0,0 +1,28 @@
+// { dg-do run }
+
+template<class T>
+const T& max(const T& a, const T& b)
+{
+ return (a < b) ? b : a;
+}
+
+signed char var_5 = -128;
+unsigned int var_11 = 2144479212U;
+unsigned long long int arr [22];
+
+void
+__attribute__((noipa))
+test(signed char var_5, unsigned var_11) {
+ for (short i_61 = 0; i_61 < var_5 + 149; i_61 += 10000)
+ arr[i_61] = max((signed char)0, var_5) ? max((signed char)1, var_5) : var_11;
+}
+
+int main() {
+ for (int i_0 = 0; i_0 < 22; ++i_0)
+ arr [i_0] = 11834725929543695741ULL;
+
+ test(var_5, var_11);
+ if (arr [0] != 2144479212ULL && arr [0] != 11834725929543695741ULL)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C
index 4deea31..4b758aa 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C
@@ -18,7 +18,7 @@ void sink (void*);
void warn_op_new ()
{
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
@@ -44,7 +44,7 @@ void warn_op_array_new ()
#define OP_NEW(n) operator new[] (n)
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C
index 45d2719..9670898 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C
@@ -4,7 +4,24 @@
{ dg-do compile }
{ dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */
-#include <new>
+#if 0
+// Avoid including <new> to make cross-compiler testing easy.
+// #include <new>
+#else
+namespace std {
+
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t { };
+extern const nothrow_t nothrow;
+
+}
+
+void* operator new (std::size_t, const std::nothrow_t &) throw ()
+ __attribute__ ((__alloc_size__ (1), __malloc__));
+void* operator new[] (std::size_t, const std::nothrow_t &) throw ()
+ __attribute__ ((__alloc_size__ (1), __malloc__));
+
+#endif
typedef __INT32_TYPE__ int32_t;
@@ -20,7 +37,7 @@ void sink (void*);
void warn_op_new ()
{
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
@@ -46,7 +63,7 @@ void warn_op_array_new ()
#define OP_NEW(n) operator new[] (n, std::nothrow)
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C
index 3f1555b..07fa351 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C
@@ -20,7 +20,7 @@ void sink (void*);
void warn_new ()
{
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
@@ -46,7 +46,7 @@ void warn_array_new ()
#define NEW(n) new char [n]
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C
index 890620d..449324a 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C
@@ -4,7 +4,24 @@
{ dg-do compile }
{ dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */
-#include <new>
+#if 0
+// Avoid including <new> to make cross-compiler testing easy.
+// #include <new>
+#else
+namespace std {
+
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t { };
+extern const nothrow_t nothrow;
+
+}
+
+void* operator new (std::size_t, const std::nothrow_t &) throw ()
+ __attribute__ ((__alloc_size__ (1), __malloc__));
+void* operator new[] (std::size_t, const std::nothrow_t &) throw ()
+ __attribute__ ((__alloc_size__ (1), __malloc__));
+
+#endif
typedef __INT32_TYPE__ int32_t;
@@ -24,7 +41,7 @@ void sink (void*);
void warn_nothrow_new ()
{
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
@@ -50,7 +67,7 @@ void warn_nothrow_array_new ()
#define NEW(n) new (std::nothrow) char [n]
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
- // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 }
+ // { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
index 64fbd08..518f9bb 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
@@ -8,7 +8,7 @@ void foo (int *);
void
bar (void)
{
- A b; // { dg-message "while referencing" }
+ A b; // { dg-message "at offset -\\d into object 'b' of size 4" "note" }
int *p = &b;
int *x = (p - 1); // { dg-warning "outside array bounds" }
foo (x);
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
index e142ea1..f4876d8 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
@@ -27,7 +27,7 @@ struct D1: virtual B, virtual C
to the opening brace. */
D1 ()
{ // { dg-warning "\\\[-Warray-bounds" "brace" }
- ci = 0; // { dg-warning "\\\[-Warray-bounds" "assign" { xfail *-*-* } }
+ ci = 0; // { dg-warning "\\\[-Warray-bounds" "assign" { xfail lp64 } }
}
};
@@ -35,7 +35,8 @@ void sink (void*);
void warn_derived_ctor_access_new_decl ()
{
- char a[sizeof (D1)]; // { dg-message "referencing 'a'" "note" }
+ char a[sizeof (D1)]; // { dg-message "at offset 1 into object 'a' of size 40" "LP64 note" { target lp64} }
+ // { dg-message "at offset 1 into object 'a' of size 20" "LP64 note" { target ilp32} .-1 }
char *p = a;
++p;
D1 *q = new (p) D1;
@@ -44,7 +45,7 @@ void warn_derived_ctor_access_new_decl ()
void warn_derived_ctor_access_new_alloc ()
{
- char *p = (char*)operator new (sizeof (D1)); // { dg-message "referencing an object of size \\d+ allocated by 'void\\\* operator new\\\(" "note" }
+ char *p = (char*)operator new (sizeof (D1)); // { dg-message "at offset 1 into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" }
++p;
D1 *q = new (p) D1;
sink (q);
@@ -52,7 +53,8 @@ void warn_derived_ctor_access_new_alloc ()
void warn_derived_ctor_access_new_array_decl ()
{
- char b[sizeof (D1) * 2]; // { dg-message "referencing 'b'" "note" }
+ char b[sizeof (D1) * 2]; // { dg-message "at offset \\d+ into object 'b' of size 80" "LP64 note" { target lp64 } }
+ // { dg-message "at offset \\d+ into object 'b' of size 40" "LP64 note" { target ilp32 } .-1 }
char *p = b;
++p;
D1 *q = new (p) D1[2];
@@ -61,7 +63,7 @@ void warn_derived_ctor_access_new_array_decl ()
void warn_derived_ctor_access_new_array_alloc ()
{
- char *p = new char[sizeof (D1) * 2]; // { dg-message "referencing an object of size \\d+ allocated by 'void\\\* operator new \\\[]\\\(" "note" }
+ char *p = new char[sizeof (D1) * 2]; // { dg-message "at offset \\d+ into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*" "note" }
++p;
D1 *q = new (p) D1[2];
sink (q);
diff --git a/gcc/testsuite/g++.dg/warn/uninit-pr55881.C b/gcc/testsuite/g++.dg/warn/uninit-pr55881.C
new file mode 100644
index 0000000..b01f4e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/uninit-pr55881.C
@@ -0,0 +1,34 @@
+/* PR middle-end/55881 - #pragma GCC diagnostic ignored ignored when inlining
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct I
+{
+ int i;
+ int foo (struct I *n)
+ {
+ return n->i + 10; // { dg-bogus "-Wmaybe-uninitialized" }
+ }
+
+ I () : i (5) {}
+};
+
+int main (int argc, char **)
+{
+ struct I i, *n;
+
+ if (argc > 10)
+ {
+ n = new I;
+ i.i = i.foo (n);
+ }
+
+ if (argc > 2)
+ {
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+ return i.foo (n);
+#pragma GCC diagnostic pop
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-29.c b/gcc/testsuite/gcc.dg/Warray-bounds-29.c
index 72c5d1c..44e5bd3 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-29.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-29.c
@@ -44,7 +44,7 @@ void test_narrow (void)
T (p1[-1]);
T (p1[ 0]);
T (p1[ 1]);
- T (p1[ 2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .char\\\[3]." } */
+ T (p1[ 2]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
T (&p1[-3]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
@@ -55,7 +55,7 @@ void test_narrow (void)
T (&p1[ 2]);
T (&p1[ 3]); /* { dg-warning "array subscript \\\[4, 6] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
- T (p2[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
+ T (p2[-4]); /* { dg-warning "subscript \\\[-2, -1\\\] is outside array bounds of .char\\\[3]." } */
T (p2[-3]);
T (p2[-2]);
T (p2[-1]);
@@ -64,19 +64,19 @@ void test_narrow (void)
/* Even though the lower bound of p3's offsets is in bounds, in order
to subtract 4 from p3 and get a dereferenceable pointer its value
would have to be out-of-bounds. */
- T (p3[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
+ T (p3[-4]); /* { dg-warning "array subscript -1 is outside array bounds of .char\\\[3]." } */
T (p3[-3]);
T (p3[-2]);
T (p3[-1]);
- T (p3[ 0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .char\\\[3]." } */
+ T (p3[ 0]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
T (p4[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
T (p4[-3]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
T (p4[-2]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
/* The final subscripts below are invalid. */
- T (p4[-1]); /* { dg-warning "array subscript \\\[3, 7] is outside array bounds of .char\\\[3]." } */
- T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .char\\\[3]." } */
+ T (p4[-1]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
+ T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
}
@@ -114,7 +114,7 @@ void test_wide (void)
T (p1[ 0]);
T (p1[ 1]);
T (p1[ 2]);
- T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p1[ 3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
T (&p1[-1]);
T (&p1[ 0]);
@@ -133,18 +133,18 @@ void test_wide (void)
/* Even though the lower bound of p3's offsets is in bounds, in order
to subtract 5 from p3 and get a dereferenceable pointer its value
would have to be out-of-bounds. */
- T (p3[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p3[-5]); /* { dg-warning "array subscript \\\[-2, -1\\\] is outside array bounds of .\[a-z \]+\\\[4]." } */
T (p3[-4]);
T (p3[-3]);
T (p3[-2]);
T (p3[-1]);
T (p3[ 0]);
- T (p3[ 1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p3[ 1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
- T (p4[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p4[-5]); /* { dg-warning "array subscript -1 is outside array bounds of .\[a-z \]+\\\[4]." } */
T (p4[-4]);
T (p4[-3]);
T (p4[-2]);
T (p4[-1]);
- T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p4[ 0]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
index 048a95d..b837ad0 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
@@ -120,7 +120,7 @@ void test_global_short_2dim_array (void)
T (&p[1]);
T (&p[2]);
T (&p[3]);
- T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" } */
+ T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" "pr??????" { xfail *-*-* } } */
T (&p[MAX]); /* { dg-warning "subscript -?\[0-9\]+ is \(above|outside\) array bounds of .short int\\\[3]" } */
}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-31.c b/gcc/testsuite/gcc.dg/Warray-bounds-31.c
index 389afaf..921461a 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-31.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-31.c
@@ -174,7 +174,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
T (*p);
p = S1 + SR (2, 3);
- T (*p); /* { dg-warning "array subscript \\\[2, 3] is outside array bounds of .char\\\[2]." } */
+ T (*p); /* { dg-warning "array subscript 2 is outside array bounds of .char\\\[2]." } */
p = S1 + SR (9, 99);
T (*p); /* { dg-warning "array subscript \\\[9, 99] is outside array bounds of .char\\\[2]." } */
@@ -198,7 +198,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
T (*p);
p = S8 + SR (9, 123);
- T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .char\\\[9]." } */
+ T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .char\\\[9]." } */
{
const char *p1 = S3 + i;
@@ -226,7 +226,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
T (*p1);
T (*p2);
T (*p3);
- T (*p4); /* { dg-warning "array subscript \\\[4, \[0-9\]+] is outside array bounds of .char\\\[4]." } */
+ T (*p4); /* { dg-warning "array subscript 4 is outside array bounds of .char\\\[4]." } */
T (*p5); /* { dg-warning "array subscript \\\[5, \[0-9\]+] is outside array bounds of .char\\\[4]." } */
}
}
@@ -241,7 +241,7 @@ void narrow_ptr_index_range (void)
T (p[SR (-8, 0)]);
T (p[SR (0, MAX)]);
T (p[SR (1, 9)]);
- T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .char\\\[8]." } */
+ T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .char\\\[8]." } */
p = S7 + SR (4, 6);
T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .char\\\[8]." } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-32.c b/gcc/testsuite/gcc.dg/Warray-bounds-32.c
index 9b5f333..02dac65 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-32.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-32.c
@@ -87,7 +87,7 @@ void wide_ptr_deref_range (ptrdiff_t i, size_t j)
T (*p);
p = W8 + SR (9, 123);
- T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .\[a-z \]+\\\[9]." } */
+ T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .\[a-z \]+\\\[9]." } */
}
void wide_ptr_index_range (void)
@@ -99,7 +99,7 @@ void wide_ptr_index_range (void)
T (p[SR (-8, 0)]);
T (p[SR (0, MAX)]);
T (p[SR (1, 9)]);
- T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .\[a-z \]+\\\[8]." } */
+ T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .\[a-z \]+\\\[8]." } */
p = W7 + SR (4, 6);
T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .\[a-z \]+\\\[8]." } */
@@ -123,7 +123,7 @@ void wide_ptr_index_range_1 (void)
int i = SR (1, 2);
const wchar_t *p1 = W2 + i;
- T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
}
}
@@ -140,17 +140,17 @@ void wide_ptr_index_range_chain (void)
T (p1[-1]);
T (p1[0]);
T (p1[1]);
- T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
- T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */
- T (p2[-4]);
+ T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -2] is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p2[-4]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */
T (p2[-1]);
T (p2[0]);
- T (p2[1]); /* { dg-warning "array subscript \\\[3, 5] is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p2[1]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
- T (p3[0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .\[a-z \]+\\\[3]." } */
- T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[3]." } */
- T (p3[9999]); /* { dg-warning "array subscript \\\[10002, 10005] is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */
+ T (p3[0]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[3]." } */
+ T (p3[9999]); /* { dg-warning "array subscript 10002 is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */
/* { dg-warning "array subscript \\\[-6382, -6379] is outside array bounds of .\[a-z \]+\\\[3]." "" { target { ! size20plus } } .-1 } */
/* Large offsets are indistinguishable from negative values. */
T (p3[DIFF_MAX]); /* { dg-warning "array subscript" "bug" { xfail *-*-* } } */
@@ -166,9 +166,9 @@ void wide_ptr_index_range_chain (void)
T (p1[-2]);
T (p1[1]);
T (p1[2]);
- T (p1[3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p1[3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
- T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */
+ T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
}
}
@@ -180,5 +180,5 @@ void wide_ptr_index_range_4 (void)
const wchar_t *p3 = p2 + i;
const wchar_t *p4 = p3 + i;
- T (p4[1]); /* { dg-warning "array subscript \\\[5, 9] is outside array bounds of .\[a-z \]+\\\[5]." } */
+ T (p4[1]); /* { dg-warning "array subscript 5 is outside array bounds of .\[a-z \]+\\\[5]." } */
}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-52.c b/gcc/testsuite/gcc.dg/Warray-bounds-52.c
index 729ad45..c7217ad 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-52.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-52.c
@@ -83,17 +83,17 @@ void ptr_idx_range (void)
i = SR (0, 1);
- T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" }
+ T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" }
T (i, (int[]){ 1 });
i = SR (1, 2);
- T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" }
+ T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" }
i = SR (2, 3);
T (i, (int[]){ 1, 2, 3 });
i = SR (3, 4);
- T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" }
+ T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" }
}
/* Some of the invalid accesses above also trigger -Wuninitialized.
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-53.c b/gcc/testsuite/gcc.dg/Warray-bounds-53.c
index 80db314..591cca2 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-53.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-53.c
@@ -83,17 +83,17 @@ void ptr_idx_range (void)
i = SR (0, 1);
- T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" }
+ T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" }
T (i, (int[]){ 1 });
i = SR (1, 2);
- T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" }
+ T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" }
i = SR (2, 3);
T (i, (int[]){ 1, 2, 3 });
i = SR (3, 4);
- T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" }
+ T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" }
}
/* Some of the invalid accesses above also trigger -Wuninitialized.
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-58.c b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
index 849457e5..616145b 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-58.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
@@ -36,7 +36,7 @@ extern struct Ax ax;
void fax_extern (void)
{
- sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
+ sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" }
sink (strlen (ax.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax.a));
sink (strlen (ax.a + 123));
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-63.c b/gcc/testsuite/gcc.dg/Warray-bounds-63.c
index a3fc918..530e2c5 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-63.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-63.c
@@ -14,7 +14,7 @@ void sink (void*);
void byte_store_to_decl (void)
{
- struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
+ struct S6 { char a[6]; } s; // { dg-message "at offset 6 into object 's' of size 6" "note" }
char *p = (char*)&s;
@@ -27,7 +27,7 @@ void byte_store_to_decl (void)
void word_store_to_decl (void)
{
- struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
+ struct S6 { char a[6]; } s; // { dg-message "at offset 5 into object 's' of size 6" "note" }
char *p = (char*)&s;
@@ -43,7 +43,7 @@ void word_store_to_decl (void)
void word_store_to_alloc (void)
{
struct S6 { char a[6]; } *p;
- p = alloca (sizeof *p); // { dg-message "referencing an object of size 6 allocated by 'alloca'" }
+ p = alloca (sizeof *p); // { dg-message "at offset 5 into object of size 6 allocated by 'alloca'" "note" }
int16_t *q = (int16_t*)((char*)p + 1);
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-66.c b/gcc/testsuite/gcc.dg/Warray-bounds-66.c
index c61891f..6ab3398 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-66.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-66.c
@@ -117,14 +117,14 @@ void test_alloca_int16_range (unsigned n)
}
{
- p = alloca (UR (0, 1)); // { dg-message "object of size between 0 and 1 allocated by '__builtin_alloca'" }
+ p = alloca (UR (0, 1)); // { dg-message "at offset \\d+ into object of size \\\[0, 1] allocated by '__builtin_alloca'" "note" }
sink (p);
T (p[0]); // { dg-warning "subscript 'int16_t {aka short int}\\\[0\\\]' is partly outside array bounds of 'unsigned char\\\[1]'" }
T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[0]'" }
}
{
- p = alloca (UR (0, 2)); // { dg-message "object of size between 0 and 2 allocated by '__builtin_alloca'" }
+ p = alloca (UR (0, 2)); // { dg-message "at offset \\d+ into object of size \\\[0, 2] allocated by '__builtin_alloca'" "note" }
sink (p);
sink (p[0]);
sink (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[1]'" }
@@ -132,7 +132,7 @@ void test_alloca_int16_range (unsigned n)
}
{
- p = alloca (UR (0, 3)); // { dg-message "object of size between 0 and 3 allocated by '__builtin_alloca'" }
+ p = alloca (UR (0, 3)); // { dg-message "at offset \\d+ into object of size \\\[0, 3] allocated by '__builtin_alloca'" "note" }
sink (p);
T (p[0]);
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
@@ -141,7 +141,7 @@ void test_alloca_int16_range (unsigned n)
}
{
- p = alloca (UR (1, 3)); // { dg-message "object of size between 1 and 3 allocated by '__builtin_alloca'" }
+ p = alloca (UR (1, 3)); // { dg-message "at offset 1|2|3 into object of size \\\[1, 3] allocated by '__builtin_alloca'" "note" }
sink (p);
T (p[0]);
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
@@ -150,7 +150,7 @@ void test_alloca_int16_range (unsigned n)
}
{
- p = alloca (UR (2, 3)); // { dg-message "object of size between 2 and 3 allocated by '__builtin_alloca'" }
+ p = alloca (UR (2, 3)); // { dg-message "at offset 2|4 into object of size \\\[2, 3] allocated by '__builtin_alloca'" "note" }
sink (p);
T (p[0]);
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
@@ -159,7 +159,7 @@ void test_alloca_int16_range (unsigned n)
}
{
- p = alloca (UR (3, 4)); // { dg-message "object of size between 3 and 4 allocated by '__builtin_alloca'" }
+ p = alloca (UR (3, 4)); // { dg-message "at offset 4|6 into object of size \\\[3, 4] allocated by '__builtin_alloca'" "note" }
sink (p);
T (p[0]);
T (p[1]);
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-69.c b/gcc/testsuite/gcc.dg/Warray-bounds-69.c
index 5a95577..80503f8 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-69.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-69.c
@@ -1,6 +1,6 @@
/* Verify that storing a bigger vector into smaller space is diagnosed.
{ dg-do compile }
- { dg-options "-O2 -Warray-bounds" } */
+ { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
typedef __INT16_TYPE__ int16_t;
typedef __attribute__ ((__vector_size__ (32))) char C32;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-71.c b/gcc/testsuite/gcc.dg/Warray-bounds-71.c
new file mode 100644
index 0000000..425bb12
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-71.c
@@ -0,0 +1,7 @@
+/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic
+ works at any call site in an inlining stack
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define IGNORE '1'
+#include "Warray-bounds-71.h"
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-71.h b/gcc/testsuite/gcc.dg/Warray-bounds-71.h
new file mode 100644
index 0000000..89d1068
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-71.h
@@ -0,0 +1,46 @@
+/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic
+ works at any call site in an inlining stack
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+int a[4];
+
+void f1 (int *p, int i)
+{
+#pragma GCC diagnostic push
+#if IGNORE == '1'
+# pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ p[i + 1] = 0;
+#pragma GCC diagnostic pop
+}
+
+void f2 (int *p, int i)
+{
+#pragma GCC diagnostic push
+#if IGNORE == '2'
+# pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ f1 (p + 1, i + 1);
+#pragma GCC diagnostic pop
+}
+
+void f3 (int *p, int i)
+{
+#pragma GCC diagnostic push
+#if IGNORE == '3'
+# pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ f2 (p + 1, i + 1);
+#pragma GCC diagnostic pop
+}
+
+void f4 (void)
+{
+#pragma GCC diagnostic push
+#if IGNORE == '4'
+# pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ f3 (a, 1);
+#pragma GCC diagnostic pop
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-72.c b/gcc/testsuite/gcc.dg/Warray-bounds-72.c
new file mode 100644
index 0000000..eb3f664
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-72.c
@@ -0,0 +1,7 @@
+/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic
+ works at any call site in an inlining stack
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define IGNORE '2'
+#include "Warray-bounds-71.h"
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-73.c b/gcc/testsuite/gcc.dg/Warray-bounds-73.c
new file mode 100644
index 0000000..50e2083
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-73.c
@@ -0,0 +1,7 @@
+/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic
+ works at any call site in an inlining stack
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define IGNORE '3'
+#include "Warray-bounds-71.h"
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-74.c b/gcc/testsuite/gcc.dg/Warray-bounds-74.c
new file mode 100644
index 0000000..c59a876
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-74.c
@@ -0,0 +1,7 @@
+/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic
+ works at any call site in an inlining stack
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define IGNORE '4'
+#include "Warray-bounds-71.h"
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-75.c b/gcc/testsuite/gcc.dg/Warray-bounds-75.c
new file mode 100644
index 0000000..306b176
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-75.c
@@ -0,0 +1,12 @@
+/* Sanity test for Warray-bounds-7[1-4].c. Also verify the expected
+ inlining stack.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#include "Warray-bounds-71.h"
+
+// { dg-regexp "In function 'f1'," "In function f1" { target *-*-* } 0 }
+// { dg-regexp "inlined from 'f2' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f2" { target *-*-* } 0 }
+// { dg-regexp "inlined from 'f3' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f3" { target *-*-* } 0 }
+// { dg-regexp "inlined from 'f4' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f4" { target *-*-* } 0 }
+// { dg-message "Warray-bounds-71.h:\\d+:\\d+: warning: array subscript 6 is outside array bounds of 'int\\\[4]'" "warning" { target *-*-* } 0 }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-76.c b/gcc/testsuite/gcc.dg/Warray-bounds-76.c
new file mode 100644
index 0000000..6711dc4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-76.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/86650 - -Warray-bounds missing inlining context
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+static void f0 (int *p, int i)
+{
+ p[i] = 0; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+// Expect two instances of the text below:
+// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 }
+// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 }
+
+static void f1 (int *p, int i) { f0 (p + 1, i + 1); }
+static void f2 (int *p, int i) { f1 (p + 1, i + 1); }
+
+extern int a2[2]; // { dg-note "'a2'" }
+
+void foo (void)
+{
+ f1 (a2 + 1, 1);
+}
+
+// { dg-regexp " +inlined from 'foo' at \[^:\]+Warray-bounds-76.c:21:\\d+:" "inlined from foo" }
+
+extern int a3[3]; // { dg-note "'a3'" }
+
+void bar (void)
+{
+ f2 (a3 + 1, 1);
+}
+
+// { dg-regexp " +inlined from 'f1' at \[^:\]+Warray-bounds-76.c:14:\\d+," "inlined from f1" }
+// { dg-regexp " +inlined from 'f2' at \[^:\]+Warray-bounds-76.c:15:\\d+," "inlined from f2" }
+// { dg-regexp " +inlined from 'bar' at \[^:\]+Warray-bounds-76.c:30:\\d+:" "inlined from bar" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-77.c b/gcc/testsuite/gcc.dg/Warray-bounds-77.c
new file mode 100644
index 0000000..6487613
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-77.c
@@ -0,0 +1,135 @@
+/* PR middle-end/100137 - -Warray-bounds false positive on varying offset
+ plus negative
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+extern char ax[], a1[1], a2[2], a3[3], a4[4], a5[5];
+
+int* ptr;
+#define X (*ptr++)
+
+
+__attribute__ ((noipa)) void
+array_plus_var_minus_cstint (int i, int j)
+{
+ {
+ const char *p = ax;
+ p += i;
+ X = p[-1];
+ X = p[-123];
+ }
+
+ {
+ const char *p = a1;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a2;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a3;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a4;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a5;
+ p += i;
+ p += j;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+}
+
+
+__attribute__ ((noipa)) void
+array_plus_var_minus_cstlong (long i, long j)
+{
+ {
+ const char *p = ax;
+ p += i;
+ X = p[-1];
+ X = p[-123];
+ }
+
+ {
+ const char *p = a1;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a2;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a3;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a4;
+ p += i;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
+ X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+
+ {
+ const char *p = a5;
+ p += i;
+ p += j;
+ X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" }
+ X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-78.c b/gcc/testsuite/gcc.dg/Warray-bounds-78.c
new file mode 100644
index 0000000..73c335f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-78.c
@@ -0,0 +1,109 @@
+/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
+ element of empty structs
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-strict-aliasing" } */
+
+typedef _Bool bool;
+
+#define NOIPA __attribute__ ((noipa))
+
+struct S { };
+
+extern struct S sa3[3];
+extern struct S sa2_3[2][3];
+extern struct S sa3_4_5[3][4][5];
+
+void sink (void*);
+
+
+NOIPA void access_sa3 (void)
+{
+ ((bool*)sa3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)sa3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)sa3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)sa3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void access_sa3_ptr (void)
+{
+ bool *p = (bool*)&sa3[0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void access_sa2_3_ptr (void)
+{
+ bool *p = (bool*)&sa2_3[0][0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+NOIPA void access_sa3_4_5_ptr (struct S s, int i)
+{
+ bool *p = (bool*)&sa3_4_5[0][0][0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+
+NOIPA void access_vla3 (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+
+ ((bool*)vla3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)vla3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)vla3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ ((bool*)vla3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+
+ sink (vla3);
+}
+
+NOIPA void access_vla3_ptr (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+ bool *p = (bool*)&vla3[0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+
+ sink (vla3);
+}
+
+NOIPA void access_vla2_3_ptr (struct S s, unsigned n)
+{
+ struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
+ bool *p = (bool*)&vla2_3[0][0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+
+ sink (vla2_3);
+}
+
+NOIPA void access_vla3_4_5_ptr (struct S s, unsigned n)
+{
+ struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
+ bool *p = (bool*)&vla3_4_5[0][0][0];
+
+ p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+ p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
+
+ sink (vla3_4_5);
+}
+
+// { dg-prune-output "empty struct has size 0 in C" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-79.c b/gcc/testsuite/gcc.dg/Warray-bounds-79.c
new file mode 100644
index 0000000..b44ac9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-79.c
@@ -0,0 +1,112 @@
+/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
+ element of empty structs
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct S
+{
+#if SOME_CONFIG_MACRO
+ /* Suppose the contents are empty in the development configuration
+ but non-empty in others. Out of bounds accesses to elements of
+ the arrays below should be diagnosed in all configurations,
+ including when S is empty, even if they are folded away. */
+ int member;
+#endif
+};
+
+extern struct S sa3[3];
+extern struct S sa2_3[2][3];
+extern struct S sa3_4_5[3][4][5];
+
+void sink (void*);
+
+
+void access_sa3 (void)
+{
+ sa3[0] = (struct S){ };
+ sa3[1] = (struct S){ };
+ sa3[2] = (struct S){ };
+ sa3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa3_ptr (void)
+{
+ struct S *p = &sa3[0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa2_3_ptr (void)
+{
+ struct S *p = &sa2_3[0][0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+void access_sa3_4_5_ptr (struct S s, int i)
+{
+ struct S *p = &sa3_4_5[0][0][0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+}
+
+
+void access_vla3 (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+
+ vla3[0] = (struct S){ };
+ vla3[1] = (struct S){ };
+ vla3[2] = (struct S){ };
+ vla3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3);
+}
+
+void access_vla3_ptr (struct S s, unsigned n)
+{
+ struct S vla3[3 < n ? 3 : n];
+ struct S *p = &vla3[0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3);
+}
+
+void access_vla2_3_ptr (struct S s, unsigned n)
+{
+ struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
+ struct S *p = &vla2_3[0][0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla2_3);
+}
+
+void access_vla3_4_5_ptr (struct S s, unsigned n)
+{
+ struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
+ struct S *p = &vla3_4_5[0][0][0];
+
+ p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
+ p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+ sink (vla3_4_5);
+}
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c
index a7d9212..e459b24 100644
--- a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c
@@ -10,23 +10,23 @@ struct A
void *p;
};
-void f0 (struct A *p, void *q) { p->p = q; }
-void f1 (struct A *p, void *q) { f0 (p, q); }
-void f2 (struct A *p, void *q) { f1 (p, q); }
+static void f0 (struct A *p, void *q) { p->p = q; }
+static void f1 (struct A *p, void *q) { f0 (p, q); }
+static void f2 (struct A *p, void *q) { f1 (p, q); }
-void g0 (struct A *p)
+static void g0 (struct A *p)
{
__builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" }
}
-void g1 (struct A *p) { g0 (p); }
-void g2 (struct A *p) { g1 (p); }
+static void g1 (struct A *p) { g0 (p); }
+static void g2 (struct A *p) { g1 (p); }
# 26 "Wfree-nonheap-object-4.c"
#define NOIPA __attribute__ ((noipa))
-extern int array[];
+extern int array[]; // { dg-message "declared here" "note on line 29" }
/* Verify the warning is issued even for calls in a system header inlined
into a function outside the header. */
@@ -39,7 +39,7 @@ NOIPA void warn_g0 (struct A *p)
g0 (p);
}
-// { dg-message "inlined from 'warn_g0'" "" { target *-*-* } 0 }
+// { dg-message "inlined from 'warn_g0'" "note on line 42" { target *-*-* } 0 }
/* Also verify the warning can be suppressed. */
@@ -65,8 +65,8 @@ NOIPA void warn_g1 (struct A *p)
g1 (p);
}
-// { dg-message "inlined from 'g1'" "" { target *-*-* } 0 }
-// { dg-message "inlined from 'warn_g1'" "" { target *-*-* } 0 }
+// { dg-message "inlined from 'g1'" "note on line 68" { target *-*-* } 0 }
+// { dg-message "inlined from 'warn_g1'" "note on line 69" { target *-*-* } 0 }
NOIPA void nowarn_g1 (struct A *p)
@@ -90,8 +90,8 @@ NOIPA void warn_g2 (struct A *p)
g2 (p);
}
-// { dg-message "inlined from 'g2'" "" { target *-*-* } 0 }
-// { dg-message "inlined from 'warn_g2'" "" { target *-*-* } 0 }
+// { dg-message "inlined from 'g2'" "note on line 93" { target *-*-* } 0 }
+// { dg-message "inlined from 'warn_g2'" "note on line 94" { target *-*-* } 0 }
NOIPA void nowarn_g2 (struct A *p)
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c
new file mode 100644
index 0000000..026cd45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c
@@ -0,0 +1,46 @@
+/* Similar to Wfree-nonheap-object-4.c but without system headers:
+ verify that warnings for the same call site from distinct callers
+ include the correct function names in the inlining stack.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct A
+{
+ void *p;
+};
+
+static void f0 (struct A *p)
+{
+ __builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+// Expect two instances of the text below:
+// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 }
+// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 }
+
+static void f1 (struct A *p) { f0 (p); }
+static void f2 (struct A *p) { f1 (p); }
+
+extern int array[];
+// Also expect two instances of the note:
+// { dg-regexp "declared here" "first note on line 24" { target *-*-* } .-2 }
+// { dg-regexp "declared here" "second note on line 24" { target *-*-* } .-3 }
+
+void foo (struct A *p)
+{
+ p->p = array + 1;
+ f0 (p);
+}
+
+// { dg-regexp " +inlined from 'foo' at \[^:\]+Wfree-nonheap-object-5.c:32:\\d+:" "note on line 32" }
+
+
+void bar (struct A *p)
+{
+ p->p = array + 2;
+ f2 (p);
+}
+
+// { dg-regexp " +inlined from 'f1' at \[^:\]+Wfree-nonheap-object-5.c:21:\\d+," "inlined from f1" }
+// { dg-regexp " +inlined from 'f2' at \[^:\]+Wfree-nonheap-object-5.c:22:\\d+," "inlined from f2" }
+// { dg-regexp " +inlined from 'bar' at \[^:\]+Wfree-nonheap-object-5.c:41:\\d+:" "inlined from bar" }
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c
new file mode 100644
index 0000000..c109558
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c
@@ -0,0 +1,49 @@
+/* Similar to Wfree-nonheap-object-5.c but with attribute artificial:
+ verify that warnings for the same call site from distinct callers
+ include the correct function names in the inlining stack.
+ { dg-do compile }
+ { dg-options "-O1 -Wall" } */
+
+struct A
+{
+ void *p;
+};
+
+__attribute__ ((always_inline, artificial))
+inline void f0 (struct A *p)
+{
+ __builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+// Expect two instances of the text below:
+// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 }
+// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 }
+
+__attribute__ ((always_inline, artificial))
+inline void f1 (struct A *p) { f0 (p); }
+__attribute__ ((always_inline, artificial))
+inline void f2 (struct A *p) { f1 (p); }
+
+extern int array[];
+// Also expect two instances of the note:
+// { dg-regexp "declared here" "first note for array" { target *-*-* } .-2 }
+// { dg-regexp "declared here" "second note for array" { target *-*-* } .-3 }
+
+void foo (struct A *p)
+{
+ p->p = array + 1;
+ f0 (p);
+}
+
+// { dg-regexp " +inlined from 'foo' at \[^:\]+Wfree-nonheap-object-6.c:35:\\d+:" "inlined from foo" }
+
+
+void bar (struct A *p)
+{
+ p->p = array + 2;
+ f2 (p);
+}
+
+// { dg-regexp " +inlined from 'f1' at \[^:\]+Wfree-nonheap-object-6.c:23:\\d+," "inlined from f1" }
+// { dg-regexp " +inlined from 'f2' at \[^:\]+Wfree-nonheap-object-6.c:25:\\d+," "inlined from f2" }
+// { dg-regexp " +inlined from 'bar' at \[^:\]+Wfree-nonheap-object-6.c:44:\\d+:" "inlined from bar" }
diff --git a/gcc/testsuite/gcc.dg/Wobjsize-1.c b/gcc/testsuite/gcc.dg/Wobjsize-1.c
index e80c8ad..2bd2f93 100644
--- a/gcc/testsuite/gcc.dg/Wobjsize-1.c
+++ b/gcc/testsuite/gcc.dg/Wobjsize-1.c
@@ -4,13 +4,17 @@
#include "Wobjsize-1.h"
char buf[6];
-/* { dg-warning "writing" "" { target *-*-* } .-1 } */
int main(int argc, char **argv)
{
- strcpy (buf,"hello ");
+ strcpy (buf,"hello "); /* { dg-warning "\\\[-Wstringop-overflow" } */
return 0;
}
-/* { dg-message "file included" "included" { target *-*-* } 0 } */
-/* { dg-message "inlined from" "inlined" { target *-*-* } 0 } */
+/* { dg-message "file included" "included" { target *-*-* } 0 }
+ { dg-message "inlined from" "inlined" { target *-*-* } 0 }
+
+ The test might emit two warnings, one for the strcpy call and
+ another for the inlined call to __builtin___strcpy_chk() called
+ from strcpy().
+ { dg-prune-output "writing 7 bytes into a region of size 6" } */
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
index a1b1039..d9ca344 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
@@ -112,7 +112,7 @@ void s2_warn_cstoff_cstidx (struct S2 *p)
void s2_warn_varoff_cstdix (struct S2 *p, int i)
{
char *q = p->a + i;
- q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
+ q[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
}
void s2_warn_cstoff_varidx (struct S2 *p, int i)
@@ -235,8 +235,8 @@ void si0_warn_cstoff_cstidx (struct Si0 *p)
void si0_warn_varoff_cstdix (struct Si0 *p, int i)
{
char *q = p->a + i;
- q[1] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
- q[9] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
+ q[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+ q[9] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
}
void si0_warn_cstoff_varidx (struct Si0 *p, int i)
@@ -248,5 +248,5 @@ void si0_warn_cstoff_varidx (struct Si0 *p, int i)
void si0_warn_varoff_varidx (struct Si0 *p, int i, int j)
{
char *q = p->a + i;
- q[j] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
+ q[j] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c
index 14ab925..6d045c5 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c
@@ -167,9 +167,7 @@ void warn_memset_reversed_range (void)
/* The following are represented as ordinary ranges with reversed bounds
and those are handled. */
T1 (p, SAR (INT_MIN, 11), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
- /* In ILP32 the offset in the following has no range info associated
- with it. */
- T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" "pr?????" { xfail ilp32 } }
+ T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
T1 (p, SAR (INT_MIN, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
/* Also represented as a true anti-range. */
T1 (p, SAR ( -12, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
index 9bfc84a..6412874 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
@@ -24,22 +24,22 @@ void nowarn_c32 (char c)
sink (p);
}
-/* The tests below fail as a result of the hack for PR 96963. However,
- with -Wall, the invalid stores are diagnosed by -Warray-bounds which
- runs before vectorization and so doesn't need the hack. If/when
- -Warray changes to use compute_objsize() this will need adjusting. */
+/* The tests below failed as a result of the hack for PR 96963. However,
+ with -Wall, the invalid stores were diagnosed by -Warray-bounds which
+ runs before vectorization and so doesn't need the hack. Now that
+ -Warray-bounds has changed to use compute_objsize() the tests pass. */
void warn_c32 (char c)
{
- extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" { xfail *-*-* } }
+ extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" }
void *p = warn_a32 + 1;
- *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
+ *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" }
/* Verify a local variable too. */
char a32[32];
p = a32 + 1;
- *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
+ *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" }
sink (p);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
index 7601679..93c54c6 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
@@ -65,7 +65,7 @@ void nowarn_cond_escape (int c, int *x)
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'" }
+ extern char a5_2[5]; // { dg-message "at offset 5 into object 'a5_2'" }
char *p;
if (c)
@@ -84,5 +84,5 @@ void warn_cond_escape (int c, int *x)
if (*x == 2)
p[2] = 0;
else if (*x == 5)
- p[5] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
+ p[5] = 0; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c
new file mode 100644
index 0000000..824dbd4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c
@@ -0,0 +1,98 @@
+#include "analyzer-decls.h"
+
+struct foo
+{
+ int i;
+ int j;
+};
+
+struct coord
+{
+ int x;
+ int y;
+ int z;
+};
+
+struct foo g;
+
+void test_1 (void)
+{
+ g.i = 42;
+ if (g.j)
+ __analyzer_eval (g.j); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (g.j); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+void test_2 (void)
+{
+ struct foo f;
+ f.i = 42;
+ if (f.j)
+ __analyzer_eval (f.j); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (f.j); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+void test_3 (struct foo *p)
+{
+ struct foo f = *p;
+ f.i = 42;
+ if (f.j)
+ __analyzer_eval (f.j); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (f.j); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+void test_4 (struct coord *p)
+{
+ struct coord f = *p;
+ f.x = 42;
+ __analyzer_eval (f.y == p->y); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.z == p->z); /* { dg-warning "TRUE" } */
+}
+
+struct s5
+{
+ char arr[8];
+};
+
+void test_5 (struct s5 *p)
+{
+ struct s5 f = *p;
+ f.arr[3] = 42;
+ __analyzer_eval (f.arr[0] == p->arr[0]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[1] == p->arr[1]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[2] == p->arr[2]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[3] == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[4] == p->arr[4]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[5] == p->arr[5]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[6] == p->arr[6]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[7] == p->arr[7]); /* { dg-warning "TRUE" } */
+}
+
+struct s6
+{
+ int before; /* Give "arr" a nonzero offset. */
+ struct foo arr[4];
+ int after;
+};
+
+void test_6 (struct s6 *p, struct foo *q)
+{
+ struct s6 f = *p;
+ f.arr[1] = *q;
+ __analyzer_eval (f.before == p->before); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[0].i == p->arr[0].i); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[0].j == p->arr[0].j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[1].i == q->i); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[1].j == q->j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[2].i == p->arr[2].i); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[2].j == p->arr[2].j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[3].i == p->arr[3].i); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.arr[3].j == p->arr[3].j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (f.after == p->after); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c b/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c
new file mode 100644
index 0000000..9a88349
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c
@@ -0,0 +1,72 @@
+#include "analyzer-decls.h"
+
+typedef __SIZE_TYPE__ size_t;
+extern void bzero (void *s, size_t n);
+extern void *memset(void *s, int c, size_t n);
+
+void test_1 (void)
+{
+ char arr[16];
+ bzero (arr, sizeof (arr));
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[7] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[8] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[9] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+
+ /* Clobber in the middle (with prefix and suffix). */
+ arr[8] = 42;
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[7] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[8] == 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval (arr[8] == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[9] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_2 (void)
+{
+ char arr[16];
+ bzero (arr, sizeof (arr));
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[1] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+
+ /* Clobber at the front (suffix, but no prefix). */
+ arr[0] = 42;
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval (arr[0] == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[1] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_3 (void)
+{
+ char arr[16];
+ bzero (arr, sizeof (arr));
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[14] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+
+ /* Clobber at the end (prefix, but no suffix). */
+ arr[15] = 42;
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[14] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval (arr[15] == 42); /* { dg-warning "TRUE" } */
+}
+
+void test_4 (void)
+{
+ char arr[16];
+ bzero (arr, sizeof (arr));
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */
+
+ /* Exact overlap, no prefix or suffix. */
+ memset (arr, 1, 16);
+ __analyzer_eval (arr[0] == 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval (arr[15] == 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval (arr[0] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[15] == 1); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
index 4a62a0e..34932da 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
@@ -503,9 +503,7 @@ void test_26 (struct coord *p, struct coord *q)
the dest value. */
*p = *q;
__analyzer_eval (p->x); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail): should have been overwritten with q->y
+ __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" } */
__analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (q->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
@@ -522,19 +520,11 @@ void test_27 (struct coord *p)
void test_28 (struct coord *p)
{
memset (p, 0, sizeof (struct coord) * 10);
- __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
- __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
+ __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" } */
- __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
- __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
+ __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" } */
__analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */
@@ -1035,8 +1025,8 @@ void test_52 (struct big b)
{
struct big d;
memcpy (&d, &b, sizeof (struct big));
- __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" } */
+ __analyzer_eval (b.ia[1023] == d.ia[1023]); /* { dg-warning "TRUE" } */
}
void test_53 (const char *msg)
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-1.c b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
index 6b62e8e..f48408e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
@@ -12,7 +12,7 @@ void test (void)
{
void *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
void **pp;
- while (get ())
+ while (get ()) /* { dg-warning "leak" } */
{
switch (get ())
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-1.c
index 5748aa1..94c5a1b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/memset-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/memset-1.c
@@ -36,22 +36,16 @@ void test_3 (int val)
{
char buf[256];
memset (buf, 'A', 256);
- /* We currently merely mark such regions as "unknown", so querying
- values within them yields UNKNOWN when ideally it would be TRUE. */
- __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
}
/* A "memset" with unknown value. */
-void test_4 (int val)
+void test_4 (char val)
{
char buf[256];
memset (buf, val, 256);
- /* We currently merely mark such regions as "unknown", so querying
- values within them yields UNKNOWN when ideally it would be TRUE. */
- __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" } */
}
/* A "memset" with unknown num bytes. */
@@ -98,6 +92,14 @@ void test_6 (int val)
__analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
}
+void test_6b (int val)
+{
+ char buf[256];
+ memset (buf, 'A', sizeof (buf));
+ memset (buf, 'B', get_zero ());
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
+}
+
/* A "memset" of known size that's not the full buffer. */
void test_7 (void)
@@ -105,10 +107,96 @@ void test_7 (void)
char buf[256];
buf[128] = 'A';
memset (buf, 0, 128);
- /* We currently merely mark the whole region as "unknown", so querying
- values within them yields UNKNOWN. */
- __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
- __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (buf[0] == '\0'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" } */
+}
+
+void test_8 (void)
+{
+ char buf[20];
+ memset (buf + 0, 0, 1);
+ memset (buf + 1, 1, 1);
+ memset (buf + 2, 2, 1);
+ memset (buf + 3, 3, 1);
+ memset (buf + 4, 4, 2);
+ memset (buf + 6, 6, 2);
+ memset (buf + 8, 8, 4);
+ memset (buf + 12, 12, 8);
+ __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 6); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 6); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[8] == 8); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[9] == 8); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[10] == 8); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[11] == 8); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[12] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[13] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[14] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[15] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[16] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[17] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[18] == 12); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[19] == 12); /* { dg-warning "TRUE" } */
+}
+
+/* Various overlapping memset calls with different sizes and values. */
+
+void test_9 (void)
+{
+ char buf[8];
+ memset (buf, 0, 8);
+ __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
+
+ memset (buf + 1, 1, 4);
+ __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
+
+ memset (buf + 2, 2, 4);
+ __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
+
+ memset (buf + 4, 3, 3);
+ __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
+
+ memset (buf + 0, 4, 3);
+ __analyzer_eval (buf[0] == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[1] == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[2] == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
new file mode 100644
index 0000000..9dd1139
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
@@ -0,0 +1,107 @@
+/* This is a very simplified version of CVE-2017-18549,
+ a use of uninitialized padding values affecting the Linux kernel
+ (and thus GPLv2).
+
+ It was fixed by e.g. 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y
+ in linux-stable. */
+
+#include "analyzer-decls.h"
+#include <string.h>
+
+typedef unsigned int __u32;
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* Adapted from include/uapi/linux/types.h */
+
+#define __bitwise
+typedef __u32 __bitwise __le32;
+
+/* Adapted from drivers/scsi/aacraid/aacraid.h */
+
+#define AAC_SENSE_BUFFERSIZE 30
+
+struct aac_srb_reply
+{
+ __le32 status;
+ __le32 srb_status;
+ __le32 scsi_status;
+ __le32 data_xfer_length;
+ __le32 sense_data_size;
+ u8 sense_data[AAC_SENSE_BUFFERSIZE];
+
+ /* Manually added to help verify the fix. */
+ u8 padding[2];
+};
+
+#define ST_OK 0
+#define SRB_STATUS_SUCCESS 0x01
+
+/* Adapted from drivers/scsi/aacraid/commctrl.c */
+
+static int aac_send_raw_srb(/* [...snip...] */)
+{
+ u32 byte_count = 0;
+
+ /* [...snip...] */
+
+ struct aac_srb_reply reply;
+
+ reply.status = ST_OK;
+
+ /* [...snip...] */
+
+ reply.srb_status = SRB_STATUS_SUCCESS;
+ reply.scsi_status = 0;
+ reply.data_xfer_length = byte_count;
+ reply.sense_data_size = 0;
+ memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
+
+ /* [...snip...] */
+
+ __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */
+ /* TODO: the following should be detected as uninitialized, when
+ that diagnostic is reimplemented. */
+ __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "UNKNOWN" } */
+}
+
+static int aac_send_raw_srb_fixed(/* [...snip...] */)
+{
+ u32 byte_count = 0;
+
+ /* [...snip...] */
+
+ struct aac_srb_reply reply;
+
+ /* This is the fix. */
+ memset(&reply, 0, sizeof(reply));
+
+ reply.status = ST_OK;
+
+ /* [...snip...] */
+
+ reply.srb_status = SRB_STATUS_SUCCESS;
+ reply.scsi_status = 0;
+ reply.data_xfer_length = byte_count;
+ reply.sense_data_size = 0;
+ memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
+
+ /* [...snip...] */
+
+ __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c
index f5424f5..7c8d1b3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c
@@ -25,11 +25,8 @@ void test_2 (void *p, void *q)
return;
foo(p);
- /* { dg-warning "pattern match on 'tmp1 == 0'" "tmp1 == 0" { target *-*-* } cond_2 } */
- /* { dg-warning "pattern match on 'tmp2 == 0'" "tmp2 == 0" { target *-*-* } cond_2 } */
- /* { dg-warning "pattern match on '<unknown> == 0'" "<unknown> == 0" { target *-*-* } cond_2 } */
- /* { dg-warning "pattern match on '<unknown> != 0'" "<unknown> != 0" { target *-*-* } cond_2 } */
/* { dg-warning "pattern match on 'p != 0'" "p != 0" { target *-*-* } cond_2 } */
+ /* { dg-warning "pattern match on 'tmp1 | tmp2 != 0'" "tmp1 | tmp2 != 0" { target *-*-* } cond_2 } */
/* { dg-warning "pattern match on 'q != 0'" "q != 0" { target *-*-* } cond_2 } */
}
@@ -44,10 +41,7 @@ void test_3 (void *p, void *q)
return;
foo(p);
- /* { dg-warning "pattern match on 'tmp1 != 0'" "tmp1 != 0" { target *-*-* } cond_3 } */
- /* { dg-warning "pattern match on 'tmp2 != 0'" "tmp2 != 0" { target *-*-* } cond_3 } */
- /* { dg-warning "pattern match on '<unknown> == 0'" "<unknown> == 0" { target *-*-* } cond_3 } */
- /* { dg-warning "pattern match on '<unknown> != 0'" "<unknown> != 0" { target *-*-* } cond_3 } */
/* { dg-warning "pattern match on 'p == 0'" "p == 0" { target *-*-* } cond_3 } */
+ /* { dg-warning "pattern match on 'tmp1 & tmp2 == 0'" "tmp1 & tmp2 == 0" { target *-*-* } cond_3 } */
/* { dg-warning "pattern match on 'q == 0'" "q == 0" { target *-*-* } cond_3 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c
new file mode 100644
index 0000000..f9c3596
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c
@@ -0,0 +1,11 @@
+/* Merger where "arr" has two different symbolic bindings. */
+
+void test (int i, int j, int flag)
+{
+ int arr[16];
+
+ if (flag)
+ arr[i] = 42;
+ else
+ arr[j] = 17;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-13.c b/gcc/testsuite/gcc.dg/builtin-bswap-13.c
new file mode 100644
index 0000000..6dc4c15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-13.c
@@ -0,0 +1,329 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int test_s32_0_1(int x) { return __builtin_bswap32(x) & 1; }
+int test_s32_0_2(int x) { return __builtin_bswap32(x) & 2; }
+int test_s32_0_240(int x) { return __builtin_bswap32(x) & 240; }
+int test_s32_0_255(int x) { return __builtin_bswap32(x) & 255; }
+int test_s32_1_1(int x) { return (__builtin_bswap32(x) >> 1) & 1; }
+int test_s32_7_1(int x) { return (__builtin_bswap32(x) >> 7) & 1; }
+int test_s32_8_1(int x) { return (__builtin_bswap32(x) >> 8) & 1; }
+int test_s32_8_240(int x) { return (__builtin_bswap32(x) >> 8) & 240; }
+int test_s32_8_255(int x) { return (__builtin_bswap32(x) >> 8) & 255; }
+int test_s32_15_1(int x) { return (__builtin_bswap32(x) >> 15) & 1; }
+int test_s32_16_1(int x) { return (__builtin_bswap32(x) >> 16) & 1; }
+int test_s32_16_240(int x) { return (__builtin_bswap32(x) >> 16) & 240; }
+int test_s32_16_255(int x) { return (__builtin_bswap32(x) >> 16) & 255; }
+int test_s32_24_1(int x) { return (__builtin_bswap32(x) >> 24) & 1; }
+int test_s32_24_240(int x) { return (__builtin_bswap32(x) >> 24) & 240; }
+int test_s32_24_255(int x) { return (__builtin_bswap32(x) >> 24) & 255; }
+int test_s32_31_1(int x) { return (__builtin_bswap32(x) >> 31) & 1; }
+
+int test_S32_0_1(int x) { return (int)__builtin_bswap32(x) & 1; }
+int test_S32_0_2(int x) { return (int)__builtin_bswap32(x) & 2; }
+int test_S32_0_240(int x) { return (int)__builtin_bswap32(x) & 240; }
+int test_S32_0_255(int x) { return (int)__builtin_bswap32(x) & 255; }
+int test_S32_1_1(int x) { return ((int)__builtin_bswap32(x) >> 1) & 1; }
+int test_S32_7_1(int x) { return ((int)__builtin_bswap32(x) >> 7) & 1; }
+int test_S32_8_1(int x) { return ((int)__builtin_bswap32(x) >> 8) & 1; }
+int test_S32_8_240(int x) { return ((int)__builtin_bswap32(x) >> 8) & 240; }
+int test_S32_8_255(int x) { return ((int)__builtin_bswap32(x) >> 8) & 255; }
+int test_S32_15_1(int x) { return ((int)__builtin_bswap32(x) >> 15) & 1; }
+int test_S32_16_1(int x) { return ((int)__builtin_bswap32(x) >> 16) & 1; }
+int test_S32_16_240(int x) { return ((int)__builtin_bswap32(x) >> 16) & 240; }
+int test_S32_16_255(int x) { return ((int)__builtin_bswap32(x) >> 16) & 255; }
+int test_S32_24_1(int x) { return ((int)__builtin_bswap32(x) >> 24) & 1; }
+int test_S32_24_240(int x) { return ((int)__builtin_bswap32(x) >> 24) & 240; }
+int test_S32_24_255(int x) { return ((int)__builtin_bswap32(x) >> 24) & 255; }
+int test_S32_31_1(int x) { return ((int)__builtin_bswap32(x) >> 31) & 1; }
+
+unsigned int test_u32_24_255(unsigned int x) {
+ return (__builtin_bswap32(x) >> 24) & 255;
+}
+
+long long test_s64_0_1(long long x) {
+ return __builtin_bswap64(x) & 1;
+}
+long long test_s64_0_2(long long x) {
+ return __builtin_bswap64(x) & 2;
+}
+long long test_s64_0_240(long long x) {
+ return __builtin_bswap64(x) & 240;
+}
+long long test_s64_0_255(long long x) {
+ return __builtin_bswap64(x) & 255;
+}
+long long test_s64_7_1(long long x) {
+ return (__builtin_bswap64(x) >> 7) & 1;
+}
+long long test_s64_8_1(long long x) {
+ return (__builtin_bswap64(x) >> 8) & 1;
+}
+long long test_s64_8_240(long long x) {
+ return (__builtin_bswap64(x) >> 56) & 240;
+}
+long long test_s64_8_255(long long x) {
+ return (__builtin_bswap64(x) >> 8) & 255;
+}
+long long test_s64_9_1(long long x) {
+ return (__builtin_bswap64(x) >> 9) & 1;
+}
+long long test_s64_31_1(long long x) {
+ return (__builtin_bswap64(x) >> 31) & 1;
+}
+long long test_s64_32_1(long long x) {
+ return (__builtin_bswap64(x) >> 32) & 1;
+}
+long long test_s64_32_240(long long x) {
+ return (__builtin_bswap64(x) >> 32) & 240;
+}
+long long test_s64_32_255(long long x) {
+ return (__builtin_bswap64(x) >> 32) & 255;
+}
+long long test_s64_33_1(long long x) {
+ return (__builtin_bswap64(x) >> 33) & 1;
+}
+long long test_s64_48_1(long long x) {
+ return (__builtin_bswap64(x) >> 48) & 1;
+}
+long long test_s64_48_240(long long x) {
+ return (__builtin_bswap64(x) >> 48) & 240;
+}
+long long test_s64_48_255(long long x) {
+ return (__builtin_bswap64(x) >> 48) & 255;
+}
+long long test_s64_56_1(long long x) {
+ return (__builtin_bswap64(x) >> 56) & 1;
+}
+long long test_s64_56_240(long long x) {
+ return (__builtin_bswap64(x) >> 56) & 240;
+}
+long long test_s64_56_255(long long x) {
+ return (__builtin_bswap64(x) >> 56) & 255;
+}
+long long test_s64_57_1(long long x) {
+ return (__builtin_bswap64(x) >> 57) & 1;
+}
+long long test_s64_63_1(long long x) {
+ return (__builtin_bswap64(x) >> 63) & 1;
+}
+
+long long test_S64_0_1(long long x) {
+ return (long long)__builtin_bswap64(x) & 1;
+}
+long long test_S64_0_2(long long x) {
+ return (long long)__builtin_bswap64(x) & 2;
+}
+long long test_S64_0_240(long long x) {
+ return (long long)__builtin_bswap64(x) & 240;
+}
+long long test_S64_0_255(long long x) {
+ return (long long)__builtin_bswap64(x) & 255;
+}
+long long test_S64_7_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 7) & 1;
+}
+long long test_S64_8_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 8) & 1;
+}
+long long test_S64_8_240(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 56) & 240;
+}
+long long test_S64_8_255(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 8) & 255;
+}
+long long test_S64_9_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 9) & 1;
+}
+long long test_S64_31_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 31) & 1;
+}
+long long test_S64_32_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 32) & 1;
+}
+long long test_S64_32_240(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 32) & 240;
+}
+long long test_S64_32_255(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 32) & 255;
+}
+long long test_S64_33_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 33) & 1;
+}
+long long test_S64_48_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 48) & 1;
+}
+long long test_S64_48_240(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 48) & 240;
+}
+long long test_S64_48_255(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 48) & 255;
+}
+long long test_S64_56_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 56) & 1;
+}
+long long test_S64_56_240(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 56) & 240;
+}
+long long test_S64_56_255(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 56) & 255;
+}
+long long test_S64_57_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 57) & 1;
+}
+long long test_S64_63_1(long long x) {
+ return ((long long)__builtin_bswap64(x) >> 63) & 1;
+}
+
+unsigned long long test_u64_56_255(unsigned long long x) {
+ return (__builtin_bswap64(x) >> 56) & 255;
+}
+
+short test_s16_0_1(short x) {
+ return __builtin_bswap16(x) & 1;
+}
+short test_s16_0_240(short x) {
+ return __builtin_bswap16(x) & 240;
+}
+short test_s16_0_255(short x) {
+ return __builtin_bswap16(x) & 255;
+}
+short test_s16_1_1(short x) {
+ return (__builtin_bswap16(x) >> 1) & 1;
+}
+short test_s16_7_1(short x) {
+ return (__builtin_bswap16(x) >> 7) & 1;
+}
+short test_s16_8_1(short x) {
+ return (__builtin_bswap16(x) >> 8) & 1;
+}
+short test_s16_8_240(short x) {
+ return (__builtin_bswap16(x) >> 8) & 240;
+}
+short test_s16_8_255(short x) {
+ return (__builtin_bswap16(x) >> 8) & 255;
+}
+short test_s16_9_1(short x) {
+ return (__builtin_bswap16(x) >> 9) & 1;
+}
+short test_s16_15_1(short x) {
+ return (__builtin_bswap16(x) >> 15) & 1;
+}
+
+short test_S16_0_1(short x) {
+ return (short)__builtin_bswap16(x) & 1;
+}
+short test_S16_0_240(short x) {
+ return (short)__builtin_bswap16(x) & 240;
+}
+short test_S16_0_255(short x) {
+ return (short)__builtin_bswap16(x) & 255;
+}
+short test_S16_1_1(short x) {
+ return ((short)__builtin_bswap16(x) >> 1) & 1;
+}
+short test_S16_7_1(short x) {
+ return ((short)__builtin_bswap16(x) >> 7) & 1;
+}
+short test_S16_8_1(short x) {
+ return ((short)__builtin_bswap16(x) >> 8) & 1;
+}
+short test_S16_8_240(short x) {
+ return ((short)__builtin_bswap16(x) >> 8) & 240;
+}
+short test_S16_8_255(short x) {
+ return ((short)__builtin_bswap16(x) >> 8) & 255;
+}
+short test_S16_9_1(short x) {
+ return ((short)__builtin_bswap16(x) >> 9) & 1;
+}
+short test_S16_15_1(short x) {
+ return ((short)__builtin_bswap16(x) >> 15) & 1;
+}
+
+unsigned short test_u16_8_255(unsigned short x) {
+ return (__builtin_bswap16(x) >> 8) & 255;
+}
+
+
+/* Shifts only */
+int test_s32_24(int x) {
+ return __builtin_bswap32(x) >> 24;
+}
+int test_s32_25(int x) {
+ return __builtin_bswap32(x) >> 25;
+}
+int test_s32_30(int x) {
+ return __builtin_bswap32(x) >> 30;
+}
+int test_s32_31(int x) {
+ return __builtin_bswap32(x) >> 31;
+}
+
+unsigned int test_u32_24(unsigned int x) {
+ return __builtin_bswap32(x) >> 24;
+}
+unsigned int test_u32_25(unsigned int x) {
+ return __builtin_bswap32(x) >> 25;
+}
+unsigned int test_u32_30(unsigned int x) {
+ return __builtin_bswap32(x) >> 30;
+}
+unsigned int test_u32_31(unsigned int x) {
+ return __builtin_bswap32(x) >> 31;
+}
+
+long long test_s64_56(long long x) {
+ return __builtin_bswap64(x) >> 56;
+}
+long long test_s64_57(long long x) {
+ return __builtin_bswap64(x) >> 57;
+}
+long long test_s64_62(long long x) {
+ return __builtin_bswap64(x) >> 62;
+}
+long long test_s64_63(long long x) {
+ return __builtin_bswap64(x) >> 63;
+}
+
+unsigned long long test_u64_56(unsigned long long x) {
+ return __builtin_bswap64(x) >> 56;
+}
+unsigned long long test_u64_57(unsigned long long x) {
+ return __builtin_bswap64(x) >> 57;
+}
+unsigned long long test_u64_62(unsigned long long x) {
+ return __builtin_bswap64(x) >> 62;
+}
+unsigned long long test_u64_63(unsigned long long x) {
+ return __builtin_bswap64(x) >> 63;
+}
+
+short test_s16_8(short x) {
+ return __builtin_bswap16(x) >> 8;
+}
+short test_s16_9(short x) {
+ return __builtin_bswap16(x) >> 9;
+}
+short test_s16_14(short x) {
+ return __builtin_bswap16(x) >> 14;
+}
+short test_s16_15(short x) {
+ return __builtin_bswap16(x) >> 15;
+}
+
+unsigned short test_u16_8(unsigned short x) {
+ return __builtin_bswap16(x) >> 8;
+}
+unsigned short test_u16_9(unsigned short x) {
+ return __builtin_bswap16(x) >> 9;
+}
+unsigned short test_u16_14(unsigned short x) {
+ return __builtin_bswap16(x) >> 14;
+}
+unsigned short test_u16_15(unsigned short x) {
+ return __builtin_bswap16(x) >> 15;
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_bswap" "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-14.c b/gcc/testsuite/gcc.dg/builtin-bswap-14.c
new file mode 100644
index 0000000..62711d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-14.c
@@ -0,0 +1,302 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+
+__attribute__ ((noinline, noclone))
+static int rt32 (int x, int y, int z) {
+ return (__builtin_bswap32(x) >> y) & z;
+}
+#define TEST32(X,Y,Z) if(((__builtin_bswap32(X)>>Y)&Z)!=rt32(X,Y,Z)) abort()
+void test32(int x)
+{
+ TEST32(x,0,1);
+ TEST32(x,0,255);
+ TEST32(x,1,1);
+ TEST32(x,2,1);
+ TEST32(x,3,1);
+ TEST32(x,4,1);
+ TEST32(x,5,1);
+ TEST32(x,6,1);
+ TEST32(x,7,1);
+ TEST32(x,8,1);
+ TEST32(x,8,255);
+ TEST32(x,9,1);
+ TEST32(x,10,1);
+ TEST32(x,11,1);
+ TEST32(x,12,1);
+ TEST32(x,13,1);
+ TEST32(x,14,1);
+ TEST32(x,15,1);
+ TEST32(x,16,1);
+ TEST32(x,16,255);
+ TEST32(x,17,1);
+ TEST32(x,18,1);
+ TEST32(x,19,1);
+ TEST32(x,20,1);
+ TEST32(x,21,1);
+ TEST32(x,22,1);
+ TEST32(x,23,1);
+ TEST32(x,24,1);
+ TEST32(x,24,255);
+ TEST32(x,25,1);
+ TEST32(x,26,1);
+ TEST32(x,27,1);
+ TEST32(x,28,1);
+ TEST32(x,29,1);
+ TEST32(x,30,1);
+ TEST32(x,31,1);
+}
+
+#if __SIZEOF_LONG_LONG__ == 8
+__attribute__ ((noinline, noclone))
+static long long rt64 (long long x, int y, long long z) {
+ return (__builtin_bswap64(x) >> y) & z;
+}
+#define TEST64(X,Y,Z) if(((__builtin_bswap64(X)>>Y)&Z)!=rt64(X,Y,Z)) abort()
+void test64(long long x)
+{
+ TEST64(x,0,1);
+ TEST64(x,0,255);
+ TEST64(x,1,1);
+ TEST64(x,2,1);
+ TEST64(x,3,1);
+ TEST64(x,4,1);
+ TEST64(x,5,1);
+ TEST64(x,6,1);
+ TEST64(x,7,1);
+ TEST64(x,8,1);
+ TEST64(x,8,255);
+ TEST64(x,9,1);
+ TEST64(x,10,1);
+ TEST64(x,11,1);
+ TEST64(x,12,1);
+ TEST64(x,13,1);
+ TEST64(x,14,1);
+ TEST64(x,15,1);
+ TEST64(x,16,1);
+ TEST64(x,16,255);
+ TEST64(x,17,1);
+ TEST64(x,18,1);
+ TEST64(x,19,1);
+ TEST64(x,20,1);
+ TEST64(x,21,1);
+ TEST64(x,22,1);
+ TEST64(x,23,1);
+ TEST64(x,24,1);
+ TEST64(x,24,255);
+ TEST64(x,25,1);
+ TEST64(x,26,1);
+ TEST64(x,27,1);
+ TEST64(x,28,1);
+ TEST64(x,29,1);
+ TEST64(x,30,1);
+ TEST64(x,31,1);
+ TEST64(x,32,1);
+ TEST64(x,32,255);
+ TEST64(x,33,1);
+ TEST64(x,34,1);
+ TEST64(x,35,1);
+ TEST64(x,36,1);
+ TEST64(x,37,1);
+ TEST64(x,38,1);
+ TEST64(x,39,1);
+ TEST64(x,40,1);
+ TEST64(x,40,255);
+ TEST64(x,41,1);
+ TEST64(x,42,1);
+ TEST64(x,43,1);
+ TEST64(x,44,1);
+ TEST64(x,45,1);
+ TEST64(x,46,1);
+ TEST64(x,47,1);
+ TEST64(x,48,1);
+ TEST64(x,48,255);
+ TEST64(x,49,1);
+ TEST64(x,50,1);
+ TEST64(x,51,1);
+ TEST64(x,52,1);
+ TEST64(x,53,1);
+ TEST64(x,54,1);
+ TEST64(x,55,1);
+ TEST64(x,56,1);
+ TEST64(x,56,255);
+ TEST64(x,57,1);
+ TEST64(x,58,1);
+ TEST64(x,59,1);
+ TEST64(x,60,1);
+ TEST64(x,61,1);
+ TEST64(x,62,1);
+ TEST64(x,63,1);
+}
+#endif
+
+__attribute__ ((noinline, noclone))
+static int rt16 (int x, int y, int z) {
+ return (__builtin_bswap16(x) >> y) & z;
+}
+#define TEST16(X,Y,Z) if(((__builtin_bswap16(X)>>Y)&Z)!=rt16(X,Y,Z)) abort()
+void test16(int x)
+{
+ TEST16(x,0,1);
+ TEST16(x,0,255);
+ TEST16(x,1,1);
+ TEST16(x,2,1);
+ TEST16(x,3,1);
+ TEST16(x,4,1);
+ TEST16(x,5,1);
+ TEST16(x,6,1);
+ TEST16(x,7,1);
+ TEST16(x,8,1);
+ TEST16(x,8,255);
+ TEST16(x,9,1);
+ TEST16(x,10,1);
+ TEST16(x,11,1);
+ TEST16(x,12,1);
+ TEST16(x,13,1);
+ TEST16(x,14,1);
+ TEST16(x,15,1);
+}
+
+int main()
+{
+ test32(0x00000000);
+ test32(0xffffffff);
+ test32(0x00000001);
+ test32(0x00000002);
+ test32(0x00000004);
+ test32(0x00000008);
+ test32(0x00000010);
+ test32(0x00000020);
+ test32(0x00000040);
+ test32(0x00000080);
+ test32(0x00000100);
+ test32(0x00000200);
+ test32(0x00000400);
+ test32(0x00000800);
+ test32(0x00001000);
+ test32(0x00002000);
+ test32(0x00004000);
+ test32(0x00008000);
+ test32(0x00010000);
+ test32(0x00020000);
+ test32(0x00040000);
+ test32(0x00080000);
+ test32(0x00100000);
+ test32(0x00200000);
+ test32(0x00400000);
+ test32(0x00800000);
+ test32(0x01000000);
+ test32(0x02000000);
+ test32(0x04000000);
+ test32(0x08000000);
+ test32(0x10000000);
+ test32(0x20000000);
+ test32(0x40000000);
+ test32(0x80000000);
+ test32(0x12345678);
+ test32(0x87654321);
+ test32(0xdeadbeef);
+ test32(0xcafebabe);
+
+#if __SIZEOF_LONG_LONG__ == 8
+ test64(0x0000000000000000ll);
+ test64(0xffffffffffffffffll);
+ test64(0x0000000000000001ll);
+ test64(0x0000000000000002ll);
+ test64(0x0000000000000004ll);
+ test64(0x0000000000000008ll);
+ test64(0x0000000000000010ll);
+ test64(0x0000000000000020ll);
+ test64(0x0000000000000040ll);
+ test64(0x0000000000000080ll);
+ test64(0x0000000000000100ll);
+ test64(0x0000000000000200ll);
+ test64(0x0000000000000400ll);
+ test64(0x0000000000000800ll);
+ test64(0x0000000000001000ll);
+ test64(0x0000000000002000ll);
+ test64(0x0000000000004000ll);
+ test64(0x0000000000008000ll);
+ test64(0x0000000000010000ll);
+ test64(0x0000000000020000ll);
+ test64(0x0000000000040000ll);
+ test64(0x0000000000080000ll);
+ test64(0x0000000000100000ll);
+ test64(0x0000000000200000ll);
+ test64(0x0000000000400000ll);
+ test64(0x0000000000800000ll);
+ test64(0x0000000001000000ll);
+ test64(0x0000000002000000ll);
+ test64(0x0000000004000000ll);
+ test64(0x0000000008000000ll);
+ test64(0x0000000010000000ll);
+ test64(0x0000000020000000ll);
+ test64(0x0000000040000000ll);
+ test64(0x0000000080000000ll);
+ test64(0x0000000100000000ll);
+ test64(0x0000000200000000ll);
+ test64(0x0000000400000000ll);
+ test64(0x0000000800000000ll);
+ test64(0x0000001000000000ll);
+ test64(0x0000002000000000ll);
+ test64(0x0000004000000000ll);
+ test64(0x0000008000000000ll);
+ test64(0x0000010000000000ll);
+ test64(0x0000020000000000ll);
+ test64(0x0000040000000000ll);
+ test64(0x0000080000000000ll);
+ test64(0x0000100000000000ll);
+ test64(0x0000200000000000ll);
+ test64(0x0000400000000000ll);
+ test64(0x0000800000000000ll);
+ test64(0x0001000000000000ll);
+ test64(0x0002000000000000ll);
+ test64(0x0004000000000000ll);
+ test64(0x0008000000000000ll);
+ test64(0x0010000000000000ll);
+ test64(0x0020000000000000ll);
+ test64(0x0040000000000000ll);
+ test64(0x0080000000000000ll);
+ test64(0x0100000000000000ll);
+ test64(0x0200000000000000ll);
+ test64(0x0400000000000000ll);
+ test64(0x0800000000000000ll);
+ test64(0x1000000000000000ll);
+ test64(0x2000000000000000ll);
+ test64(0x4000000000000000ll);
+ test64(0x8000000000000000ll);
+ test64(0x0123456789abcdefll);
+ test64(0xfedcba9876543210ll);
+ test64(0xdeadbeefdeadbeefll);
+ test64(0xcafebabecafebabell);
+#endif
+
+ test16(0x0000);
+ test16(0xffff);
+ test16(0x0001);
+ test16(0x0002);
+ test16(0x0004);
+ test16(0x0008);
+ test16(0x0010);
+ test16(0x0020);
+ test16(0x0040);
+ test16(0x0080);
+ test16(0x0100);
+ test16(0x0200);
+ test16(0x0400);
+ test16(0x0800);
+ test16(0x1000);
+ test16(0x2000);
+ test16(0x4000);
+ test16(0x8000);
+ test16(0x1234);
+ test16(0x4321);
+ test16(0xdead);
+ test16(0xbeef);
+ test16(0xcafe);
+ test16(0xbabe);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c
index 440623c3..2984a33 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c
@@ -11,7 +11,6 @@
[2] int 'unsigned int' size=4 offset=0 bits=32
[3] struct 'bitt' size=4
member 'f' type=1 bitfield_size=2 bit_offset=0
- member 'data' type=2 bitfield_size=14 bit_offset=2
*/
/* { dg-do compile } */
@@ -19,15 +18,12 @@
/* Enum with 4 members. */
/* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */
-/* Struct with bitfield members, and 2 members. */
-/* { dg-final { scan-assembler-times "\[\t \]0x84000002\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* Struct with 1 bitfield member. */
+/* { dg-final { scan-assembler-times "\[\t \]0x84000001\[\t \]+\[^\n\]*btt_info" 1 } } */
/* Bitfield "f" points to type ID 1. */
/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btm_type" 1 } } */
-/* Bitfield "data" points to type ID 2. */
-/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btm_type" 1 } } */
-
enum foo
{
BAR = 0,
@@ -39,5 +35,4 @@ enum foo
struct bitt
{
enum foo f : 2;
- unsigned data : 14;
} bitty;
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c
index 79e9f52..33e2f64 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c
@@ -23,6 +23,7 @@
/* { dg-do compile } */
/* { dg-options "-O0 -gbtf -dA" } */
+/* { dg-options "-O0 -gbtf -gdwarf-4 -dA" { target { *-*-darwin* } } } */
/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
index 88ae4c4..f809d93 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
@@ -11,6 +11,7 @@
/* { dg-do compile ) */
/* { dg-options "-O0 -gbtf -dA" } */
+/* { dg-options "-O0 -gbtf -dA -msdata=none" { target { { powerpc*-*-* } && ilp32 } } } */
/* Check for two DATASEC entries with vlen 3, and one with vlen 1. */
/* { dg-final { scan-assembler-times "0xf000003\[\t \]+\[^\n\]*btt_info" 2 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c
new file mode 100644
index 0000000..6876df0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c
@@ -0,0 +1,20 @@
+/* Tests for BTF floating point type kinds. We expect a single record for each
+ of the base types: float, double and long double. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0 -gbtf -dA" } */
+
+/* { dg-final { scan-assembler-times "\[\t \]0x10000000\[\t \]+\[^\n\]*btt_info" 3 } } */
+
+/* { dg-final { scan-assembler-times "ascii \"float.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"double.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"long double.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+
+float a;
+float b = 1.5f;
+
+double c;
+double d = -99.9;
+
+long double e;
+long double f = 1000.01;
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c
index 35f96a2..c83b823 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c
@@ -16,7 +16,7 @@
/* Exactly one function parameter should have type_id=0. */
/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*farg_type" 1 } } */
-int foo (int a, float f, long b)
+int foo (int a, float __attribute__((__vector_size__(16))) f, long b)
{
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
index 24514fc..c3aff09 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
@@ -14,6 +14,6 @@
struct with_float
{
int a;
- float f;
+ float __attribute__((__vector_size__(16))) f;
char c;
} instance;
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c
index 0f9742e..db0bdd7 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c
@@ -16,7 +16,7 @@
/* { dg-final { scan-assembler-times "ascii \"myst.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
int foo;
-float bar;
+float __attribute__((__vector_size__(16))) bar;
int baz[10];
struct st
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf.exp b/gcc/testsuite/gcc.dg/debug/btf/btf.exp
index e72a2be..e173515 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf.exp
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf.exp
@@ -24,6 +24,11 @@ if { [istarget nvptx-*-*] } {
return
}
+if { [istarget "powerpc-ibm-aix*"] } {
+ set torture_execute_xfail "powerpc-ibm-aix*"
+ return
+}
+
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c
index fc3af03..c4801a7 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c
@@ -1,7 +1,10 @@
/* Test CTF generation works well with ((mode)) attribute.
In this testcase, CTF should report type of bqi to be an enum and
- not an int. */
+ not an int. Also, CTF for typedef of enum should exist. However, there
+ are no direct and portable methods of checking that a CTF type / CTF
+ variable refers to a specific CTF type, so this testcase merely asserts
+ for existence of individual CTF records. */
/* { dg-do compile ) */
/* { dg-options "-O0 -gctf -dA" } */
@@ -16,7 +19,5 @@
/* { dg-final { scan-assembler-times "\[\t \]0x22000003\[\t \]+\[^\n\]*ctt_info" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */
-/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*ctv_typeidx" 1} } */
-
typedef enum { B1 = 1, B2 = 2, B3 = 3 } B;
B __attribute__ ((mode (QI))) bqi;
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c
index 9368d47..0137e9d 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c
@@ -31,6 +31,7 @@
/* { dg-do compile ) */
/* { dg-options "-O0 -gctf -dA" } */
+/* { dg-options "-O0 -gctf -gdwarf-4 -dA" { target { *-*-darwin* } } } */
/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 7 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c
index 7c8b17d..79d5cb2 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c
@@ -13,5 +13,6 @@
/* { dg-options "-gctf" } */
/* { dg-require-effective-target float16 } */
+/* { dg-add-options float16 } */
_Float16 f16;
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c
index f4374e6..7033121 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c
@@ -14,6 +14,8 @@
/* { dg-require-effective-target float64 } */
/* { dg-require-effective-target float64x } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float64x } */
_Float64 f64;
_Float64x f64x;
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c
index 9e698fd..37094b5d 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c
@@ -10,6 +10,6 @@
/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*cta_nelems" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctm_offset" 1 } } */
-/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctm_offset" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x20\[\t \]+\[^\n\]*ctm_offset" 1 } } */
static struct ranges {int from, to;} lim_regs[] = {{ 16, 7}, { 16, 6}, { 20, 7},{ 20, 6}};
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp
index 46055f8..0b650ed 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp
@@ -24,6 +24,11 @@ if { [istarget nvptx-*-*] } {
return
}
+if { [istarget "powerpc-ibm-aix*"] } {
+ set torture_execute_xfail "powerpc-ibm-aix*"
+ return
+}
+
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
diff --git a/gcc/testsuite/gcc.dg/debug/pr57351.c b/gcc/testsuite/gcc.dg/debug/pr57351.c
index 972f3e9..236d74d 100644
--- a/gcc/testsuite/gcc.dg/debug/pr57351.c
+++ b/gcc/testsuite/gcc.dg/debug/pr57351.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_neon } */
+/* { dg-require-effective-target arm_arch_v7a_ok } */
/* { dg-options "-std=c99 -Os -g -march=armv7-a" } */
/* { dg-add-options arm_neon } */
diff --git a/gcc/testsuite/gcc.dg/format/c90-printf-1.c b/gcc/testsuite/gcc.dg/format/c90-printf-1.c
index c8652fc..8ffd63f 100644
--- a/gcc/testsuite/gcc.dg/format/c90-printf-1.c
+++ b/gcc/testsuite/gcc.dg/format/c90-printf-1.c
@@ -240,7 +240,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */
printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */
printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */
- printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */
+ printf ("%s", (char *)0); /* { dg-warning "12:'%s' directive argument is null" "%s with NULL" } */
/* Test for correct column locations within strings with embedded
escape sequences. */
printf ("\\\a\n \"\t%5n\n", n); /* { dg-warning "25:width" "width with %n" } */
diff --git a/gcc/testsuite/gcc.dg/format/gcc_diag-10.c b/gcc/testsuite/gcc.dg/format/gcc_diag-10.c
index a2f99fe..dd930f9 100644
--- a/gcc/testsuite/gcc.dg/format/gcc_diag-10.c
+++ b/gcc/testsuite/gcc.dg/format/gcc_diag-10.c
@@ -64,8 +64,8 @@ void test_cdiag (tree t, gimple *gc)
cdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cdiag ("%E", t);
cdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */
- cdiag ("%G", gc);
- cdiag ("%K", t);
+ cdiag ("%G", gc); /* { dg-warning "format" } */
+ cdiag ("%K", t); /* { dg-warning "format" } */
cdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
cdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */
@@ -80,8 +80,8 @@ void test_cdiag (tree t, gimple *gc)
cdiag ("%<%D%>", t);
cdiag ("%<%E%>", t);
cdiag ("%<%F%>", t);
- cdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */
- cdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
+ cdiag ("%<%G%>", gc); /* { dg-warning "format" } */
+ cdiag ("%<%K%>", t); /* { dg-warning "format" } */
cdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
cdiag ("%<%r%>", ""); /* { dg-warning "unterminated color directive" } */
@@ -103,8 +103,8 @@ void test_tdiag (tree t, gimple *gc)
tdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
tdiag ("%E", t);
- tdiag ("%G", gc);
- tdiag ("%K", t);
+ tdiag ("%G", gc); /* { dg-warning "format" } */
+ tdiag ("%K", t); /* { dg-warning "format" } */
tdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
tdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */
@@ -118,8 +118,8 @@ void test_tdiag (tree t, gimple *gc)
tdiag ("%<%D%>", t);
tdiag ("%<%E%>", t);
- tdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */
- tdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
+ tdiag ("%<%G%>", gc); /* { dg-warning "format" } */
+ tdiag ("%<%K%>", t); /* { dg-warning "format" } */
tdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
tdiag ("%<%r%>", ""); /* { dg-warning "unterminated color directive" } */
@@ -138,8 +138,8 @@ void test_cxxdiag (tree t, gimple *gc)
cxxdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cxxdiag ("%E", t);
cxxdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */
- cxxdiag ("%G", gc);
- cxxdiag ("%K", t);
+ cxxdiag ("%G", gc); /* { dg-warning "format" } */
+ cxxdiag ("%K", t); /* { dg-warning "format" } */
cxxdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
cxxdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr101066.c b/gcc/testsuite/gcc.dg/ipa/pr101066.c
new file mode 100644
index 0000000..1ceb6e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr101066.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-Os -fno-ipa-cp -fno-inline" } */
+
+int a = 1, c, d, e;
+int *b = &a;
+static int g(int *h) {
+ c = *h;
+ return d;
+}
+static void f(int *h) {
+ e = *h;
+ *b = 0;
+ g(h);
+}
+int main() {
+ f(b);
+ if (c)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
index 05133d5..61dd490 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -53,13 +53,6 @@ public:
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,
@@ -365,20 +358,6 @@ gil_state_machine::on_stmt (sm_context *sm_ctxt,
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
{
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c
index 02c4629..d2bfca0 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c
@@ -133,7 +133,7 @@ test_inlining (gimple *stmt)
return;
}
- warning_at (call->location, 0, "%G%s", call,
+ warning_at (call->location, 0, "%s",
TREE_STRING_POINTER (t_string));
}
diff --git a/gcc/testsuite/gcc.dg/pr101223.c b/gcc/testsuite/gcc.dg/pr101223.c
new file mode 100644
index 0000000..6d5a247
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr101223.c
@@ -0,0 +1,44 @@
+/* PR tree-optimization/101223 */
+/* { dg-do run } */
+/* { dg-options "-O2 " } */
+
+struct {
+ int a : 1;
+} b;
+int c = 1, d;
+int foo1() {
+ for (; d < 2; d++) {
+ int e = ~c, f = 0, g;
+ if (e) {
+ f = c;
+ g = b.a;
+ b.a = f;
+ if (b.a >= g)
+ __builtin_abort();
+ }
+ c = f;
+ b.a = g;
+ }
+ return 0;
+}
+
+int foo2() {
+ for (; d < 2; d++) {
+ int e = ~c, f = 0, g;
+ if (e) {
+ f = c;
+ g = b.a;
+ b.a = f;
+ if (g <= b.a)
+ __builtin_abort();
+ }
+ c = f;
+ b.a = g;
+ }
+ return 0;
+}
+int main ()
+{
+ return foo1() + foo2();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr101266.c b/gcc/testsuite/gcc.dg/pr101266.c
new file mode 100644
index 0000000..d198089
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr101266.c
@@ -0,0 +1,8 @@
+/* PR debug/101266 */
+/* { dg-do compile } */
+/* { dg-options "-g -O2" } */
+
+void
+foo (int (*p)[(int){1}])
+{
+}
diff --git a/gcc/testsuite/gcc.dg/pr101294.c b/gcc/testsuite/gcc.dg/pr101294.c
new file mode 100644
index 0000000..ca59b35
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr101294.c
@@ -0,0 +1,15 @@
+/* PR middle-end/101294 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-mavx" { target avx } } */
+
+typedef __attribute__((__vector_size__ (sizeof (unsigned long long)))) unsigned long long U;
+typedef __attribute__((__vector_size__ (4 * sizeof (unsigned long long)))) unsigned long long V;
+
+extern U x;
+
+void
+foo (void)
+{
+ x = __builtin_shufflevector ((U){}, (V){}, 3);
+}
diff --git a/gcc/testsuite/gcc.dg/pr101403.c b/gcc/testsuite/gcc.dg/pr101403.c
new file mode 100644
index 0000000..ac5fa79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr101403.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+unsigned int foo (unsigned int a)
+{
+ unsigned int u;
+ unsigned short b = __builtin_bswap16 (a);
+ return b >> (u, 12);
+}
+
+int main (void)
+{
+ unsigned int x = foo (0x80);
+ if (x != 0x0008)
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr79214.c b/gcc/testsuite/gcc.dg/pr79214.c
index 3f5d935..2f93eed 100644
--- a/gcc/testsuite/gcc.dg/pr79214.c
+++ b/gcc/testsuite/gcc.dg/pr79214.c
@@ -22,67 +22,67 @@ static size_t range (void)
void test_bzero (void)
{
- bzero (d, range ()); /* { dg-warning ".__builtin_(bzero|memset). writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ bzero (d, range ()); /* { dg-warning ".__builtin_(bzero|memset). writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
void test_memcpy (void)
{
- memcpy (d, s, range ()); /* { dg-warning ".__builtin_memcpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ memcpy (d, s, range ()); /* { dg-warning ".__builtin_memcpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
void test_memmove (void)
{
- memmove (d, d + 1, range ()); /* { dg-warning ".__builtin_memmove. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ memmove (d, d + 1, range ()); /* { dg-warning ".__builtin_memmove. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
void test_mempcpy (void)
{
- mempcpy (d, s, range ()); /* { dg-warning ".__builtin_mempcpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ mempcpy (d, s, range ()); /* { dg-warning ".__builtin_mempcpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
void test_memset (int n)
{
- memset (d, n, range ()); /* { dg-warning ".__builtin_memset. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ memset (d, n, range ()); /* { dg-warning ".__builtin_memset. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
void test_strcat (int i)
{
const char *s = i < 0 ? "123" : "4567";
- strcat (d, s); /* { dg-warning ".__builtin_strcat. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */
+ strcat (d, s); /* { dg-warning ".__builtin_strcat. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
char* test_stpcpy (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return stpcpy (d, s); /* { dg-warning ".__builtin_stpcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */
+ return stpcpy (d, s); /* { dg-warning ".__builtin_stpcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
char* test_stpncpy (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return stpncpy (d, s, range ()); /* { dg-warning ".__builtin_stpncpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ return stpncpy (d, s, range ()); /* { dg-warning ".__builtin_stpncpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
char* test_strcpy (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return strcpy (d, s); /* { dg-warning ".__builtin_strcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */
+ return strcpy (d, s); /* { dg-warning ".__builtin_strcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
char* test_strncpy (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return strncpy (d, s, range ()); /* { dg-warning ".__builtin_strncpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */
+ return strncpy (d, s, range ()); /* { dg-warning ".__builtin_strncpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */
}
char* test_strncat (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound \\\[4, \[0-9\]+] exceeds destination size 3" } */
+ return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound \\\[4, \[0-9\]+] exceeds destination size 3" "pr?????" { xfail { *-*-* } } } */
}
diff --git a/gcc/testsuite/gcc.dg/pragma-diag-10.c b/gcc/testsuite/gcc.dg/pragma-diag-10.c
new file mode 100644
index 0000000..127b299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-diag-10.c
@@ -0,0 +1,20 @@
+/* PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective
+ in conjunction with alias attribute
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+void *
+__rawmemchr_ppc (const void *s, int c)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#pragma GCC diagnostic ignored "-Wstringop-overread"
+ if (c != 0)
+ return __builtin_memchr (s, c, (unsigned long)-1); // { dg-bogus "specified bound \\d+ exceeds maximum object size" }
+#pragma GCC diagnostic pop
+
+ return (char *)s + __builtin_strlen (s);
+}
+
+extern __typeof (__rawmemchr_ppc) __EI___rawmemchr_ppc
+ __attribute__((alias ("__rawmemchr_ppc")));
diff --git a/gcc/testsuite/gcc.dg/pragma-diag-9.c b/gcc/testsuite/gcc.dg/pragma-diag-9.c
new file mode 100644
index 0000000..9aac379
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-diag-9.c
@@ -0,0 +1,141 @@
+/* Verify that #pragma GCC diagnostic down the inlining stack suppresses
+ a warning that would otherwise be issued for inlined calls higher up
+ the inlining stack.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+extern void* memset (void*, int, __SIZE_TYPE__);
+
+static void warn0 (int *p)
+{
+ memset (p, __LINE__, 3); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+static void warn1 (int *p)
+{
+ warn0 (p + 1);
+}
+
+static void warn2 (int *p)
+{
+ warn1 (p + 1);
+}
+
+int a2[2]; // { dg-message "at offset 12 into destination object 'a2' of size 8" }
+
+void warn3 (void)
+{
+ warn2 (a2 + 1);
+}
+
+
+// Verify suppression at the innermost frame of the inlining stack.
+
+static void ignore0 (int *p)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ memset (p, __LINE__, 3);
+#pragma GCC diagnostic pop
+}
+
+static void nowarn1_ignore0 (int *p)
+{
+ ignore0 (p + 1);
+}
+
+static void nowarn2_ignore0 (int *p)
+{
+ nowarn1_ignore0 (p + 1);
+}
+
+int b2[2];
+
+void nowarn3_ignore0 (void)
+{
+ nowarn2_ignore0 (b2 + 1);
+}
+
+
+// Verify suppression at the second innermost frame of the inlining stack.
+
+static void nowarn0_ignore1 (int *p)
+{
+ memset (p, __LINE__, 3);
+}
+
+static void ignore1 (int *p)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ nowarn0_ignore1 (p + 1);
+#pragma GCC diagnostic pop
+}
+
+void nowarn2_ignore1 (int *p)
+{
+ ignore1 (p + 1);
+}
+
+int c2[2];
+
+void nowarn3_ignore1 (void)
+{
+ nowarn2_ignore1 (c2 + 1);
+}
+
+
+// Verify suppression at the third innermost frame of the inlining stack.
+
+static void nowarn0_ignore2 (int *p)
+{
+ memset (p, __LINE__, 3);
+}
+
+static void nowarn1_ignore2 (int *p)
+{
+ nowarn0_ignore2 (p + 1);
+}
+
+static void ignore2 (int *p)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ nowarn1_ignore2 (p + 1);
+#pragma GCC diagnostic pop
+}
+
+int d2[2];
+
+void nowarn3_ignore2 (void)
+{
+ ignore2 (c2 + 1);
+}
+
+
+// Verify suppression at the outermost frame of the inlining stack.
+
+static void nowarn0_ignore3 (int *p)
+{
+ memset (p, __LINE__, 3);
+}
+
+static void nowarn1_ignore3 (int *p)
+{
+ nowarn0_ignore3 (p + 1);
+}
+
+static void nowarn2_ignore3 (int *p)
+{
+ nowarn1_ignore3 (p + 1);
+}
+
+int e2[2];
+
+void ignore3 (void)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ nowarn2_ignore3 (e2 + 1);
+#pragma GCC diagnostic pop
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr100329.c b/gcc/testsuite/gcc.dg/torture/pr100329.c
index b90700d..2a4331b 100644
--- a/gcc/testsuite/gcc.dg/torture/pr100329.c
+++ b/gcc/testsuite/gcc.dg/torture/pr100329.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile { target lra } } */
/* { dg-additional-options "--param tree-reassoc-width=2" } */
unsigned int a0;
diff --git a/gcc/testsuite/gcc.dg/torture/pr100519.c b/gcc/testsuite/gcc.dg/torture/pr100519.c
index faf6e24..89dff66 100644
--- a/gcc/testsuite/gcc.dg/torture/pr100519.c
+++ b/gcc/testsuite/gcc.dg/torture/pr100519.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile { target lra } } */
/* { dg-additional-options "--param tree-reassoc-width=2" } */
unsigned int foo_a1, foo_a2;
diff --git a/gcc/testsuite/gcc.dg/torture/pr100778.c b/gcc/testsuite/gcc.dg/torture/pr100778.c
new file mode 100644
index 0000000..7997f2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr100778.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target *-*-*gnu* } } */
+/* { dg-additional-options "-fno-tree-sink -fno-math-errno -ftree-vectorize -D_GNU_SOURCE" } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+double a[2];
+void __attribute__((noipa)) foo ()
+{
+ double x = a[0];
+ double y = a[1];
+ double norm = __builtin_sqrt (x*x + y*y);
+ if (norm > 1.)
+ {
+ x = x / norm;
+ y = y / norm;
+ }
+ a[0] = x;
+ a[1] = y;
+}
+
+int main()
+{
+ feenableexcept (FE_INVALID);
+ a[0] = 0.;
+ a[1] = 0.;
+ foo ();
+ if (a[0] != 0. || a[1] != 0.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr101278.c b/gcc/testsuite/gcc.dg/torture/pr101278.c
new file mode 100644
index 0000000..1d25658
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr101278.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+struct X { int counter; };
+
+struct X __attribute__((noipa)) foo (struct X x)
+{
+ x.counter++;
+ if (x.counter == 5)
+ __builtin_exit (0);
+ return x;
+}
+
+int
+main ()
+{
+ struct X x;
+ x.counter = 0;
+ for (int i = 0; i < 10; ++i)
+ x = foo (x);
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c
new file mode 100644
index 0000000..8188dd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c
@@ -0,0 +1,20 @@
+/* PR middle-end/100325 - missing warning with -O0 on sprintf overflow with
+ pointer plus offset
+ { dg-do compile }
+ { dg-options "-O0 -Wall" } */
+
+#define S(n) (&"0123456789"[10 - n])
+
+extern int sprintf (char*, const char*, ...);
+
+char d[10];
+
+void nowarn_d10_s9 ()
+{
+ sprintf (d, "%s", S (9)); // { dg-bogus "-Wformat-overflow" }
+}
+
+void warn_d10_s10 ()
+{
+ sprintf (d, "%s", S (10)); // { dg-warning "-Wformat-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c
new file mode 100644
index 0000000..781555e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c
@@ -0,0 +1,22 @@
+/* PR/101280 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-linterchange-details" } */
+
+void dummy (double *, double *);
+#define LEN_2D 32
+double aa[LEN_2D][LEN_2D], bb[LEN_2D][LEN_2D];
+double s231(int iterations)
+{
+// loop interchange
+// loop with data dependency
+ for (int nl = 0; nl < 100*(iterations/LEN_2D); nl++) {
+ for (int i = 0; i < LEN_2D; ++i) {
+ for (int j = 1; j < LEN_2D; j++) {
+ aa[j][i] = aa[j - 1][i] + bb[j][i];
+ }
+ }
+ dummy(aa[0],bb[0]);
+ }
+}
+
+/* { dg-final { scan-tree-dump "loops interchanged" "linterchange" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c
index ac3018e..6aec689 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c
@@ -9,4 +9,6 @@ foo (int i)
return i;
}
-/* { dg-final { scan-tree-dump-not "ABS" "optimized" } } */
+/* We should not have ABS_EXPR but ABSU_EXPR instead. */
+/* { dg-final { scan-tree-dump-not "ABS_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump "ABSU" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c
new file mode 100644
index 0000000..ff658cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c
@@ -0,0 +1,44 @@
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+int f0(int A)
+{
+// A == 0? A : -A same as -A
+ if (A == 0) return A;
+ return -A;
+}
+
+int f1(int A)
+{
+// A != 0? A : -A same as A
+ if (A != 0) return A;
+ return -A;
+}
+int f2(int A)
+{
+// A >= 0? A : -A same as abs (A)
+ if (A >= 0) return A;
+ return -A;
+}
+int f3(int A)
+{
+// A > 0? A : -A same as abs (A)
+ if (A > 0) return A;
+ return -A;
+}
+int f4(int A)
+{
+// A <= 0? A : -A same as -abs (A)
+ if (A <= 0) return A;
+ return -A;
+}
+int f5(int A)
+{
+// A < 0? A : -A same as -abs (A)
+ if (A < 0) return A;
+ return -A;
+}
+
+/* These should be optimized in phiopt1 but is confused by predicts. */
+/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c
new file mode 100644
index 0000000..eb89dec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c
@@ -0,0 +1,44 @@
+/* { dg-options "-O2 -fno-signed-zeros -fdump-tree-phiopt" } */
+
+float f0(float A)
+{
+// A == 0? A : -A same as -A
+ if (A == 0) return A;
+ return -A;
+}
+
+float f1(float A)
+{
+// A != 0? A : -A same as A
+ if (A != 0) return A;
+ return -A;
+}
+float f2(float A)
+{
+// A >= 0? A : -A same as abs (A)
+ if (A >= 0) return A;
+ return -A;
+}
+float f3(float A)
+{
+// A > 0? A : -A same as abs (A)
+ if (A > 0) return A;
+ return -A;
+}
+float f4(float A)
+{
+// A <= 0? A : -A same as -abs (A)
+ if (A <= 0) return A;
+ return -A;
+}
+float f5(float A)
+{
+// A < 0? A : -A same as -abs (A)
+ if (A < 0) return A;
+ return -A;
+}
+
+/* These should be optimized in phiopt1 but is confused by predicts. */
+/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
new file mode 100644
index 0000000..5efb956
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
@@ -0,0 +1,18 @@
+/* PR/101293 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim2-details" } */
+
+struct X { int i; int j; };
+
+void foo(struct X *x, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ int *p = &x->j;
+ int tem = *p;
+ x->j += tem * i;
+ }
+}
+
+/* Make sure LIM can handle unifying MEM[x, 4] and MEM[x].j */
+/* { dg-final { scan-tree-dump "Executing store motion" "lim2" } } */
diff --git a/gcc/testsuite/gcc.dg/uninit-suppress_3.c b/gcc/testsuite/gcc.dg/uninit-suppress_3.c
new file mode 100644
index 0000000..7bbe9ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-suppress_3.c
@@ -0,0 +1,98 @@
+/* PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at declaration
+ site
+ { dg-do compile }
+ { dg-options "-O1 -Wall" } */
+
+struct A
+{
+ int x;
+};
+
+// Verify that suppression works at every inlining level.
+
+static int f0 (int *x)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
+ return ++*x;
+
+#pragma GCC diagnostic pop
+}
+
+static int f1 (int *p, int n)
+{
+ struct A a;
+ for (int i = 0; i < n; ++i) {
+ if (p[i] > 1) {
+ a = (struct A){p[i]};
+ }
+ }
+
+ return f0 (&a.x);
+}
+
+int f2 (void)
+{
+ int a[] = { 1, 2, 3, 4 };
+ return f1 (a, 4);
+}
+
+
+static int g0 (int *x)
+{
+ return ++*x;
+}
+
+static int g1 (int *p, int n)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
+ struct A a;
+ for (int i = 0; i < n; ++i) {
+ if (p[i] > 1) {
+ a = (struct A){p[i]};
+ }
+ }
+
+ return g0 (&a.x);
+
+#pragma GCC diagnostic pop
+}
+
+int g2 (void)
+{
+ int a[] = { 1, 2, 3, 4, 5 };
+ return g1 (a, 5);
+}
+
+
+static int h0 (int *x)
+{
+ return ++*x;
+}
+
+static int h1 (int *p, int n)
+{
+ struct A a;
+ for (int i = 0; i < n; ++i) {
+ if (p[i] > 1) {
+ a = (struct A){p[i]};
+ }
+ }
+
+ return h0 (&a.x);
+}
+
+int h2 (void)
+{
+ int a[] = { 1, 2, 3, 4, 5, 6 };
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
+ return h1 (a, 6);
+
+#pragma GCC diagnostic pop
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-72.c b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c
new file mode 100644
index 0000000..5b243fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+double x[2], y[2], z[2], w[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = x[1] + y[1];
+ double tem1 = x[0] - y[0];
+ double tem2 = z[1] * tem0;
+ double tem3 = z[0] * tem1;
+ z[0] = tem2 - w[0];
+ z[1] = tem3 + w[1];
+}
+
+int main()
+{
+ check_vect ();
+
+ x[0] = 1.; x[1] = 2.;
+ y[0] = 7.; y[1] = -5.;
+ z[0] = 2.; z[1] = 3.;
+ w[0] = 9.; w[1] = -5.;
+ foo ();
+ if (z[0] != -18. || z[1] != -17.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-73.c b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c
new file mode 100644
index 0000000..d4c8a51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+double x[2], y[2], z[2], w[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = x[1] + y[1];
+ double tem1 = x[0] - y[0];
+ double tem2 = z[1] * tem0;
+ double tem3 = z[0] * tem1;
+ z[0] = tem2 - w[1];
+ z[1] = tem3 + w[0];
+}
+
+int main()
+{
+ check_vect ();
+
+ x[0] = 1.; x[1] = 2.;
+ y[0] = 7.; y[1] = -5.;
+ z[0] = 2.; z[1] = 3.;
+ w[0] = 9.; w[1] = -5.;
+ foo ();
+ if (z[0] != -4. || z[1] != -3.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-74.c b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c
new file mode 100644
index 0000000..9c1ebb7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
+
+double a[2], b[2], c[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = a[1] + b[1];
+ double tem1 = a[0] - b[0];
+ c[0] = 2. * tem0;
+ c[1] = 5. * tem1;
+}
+
+int main()
+{
+ check_vect ();
+
+ a[0] = 1.; a[1] = 3.;
+ b[0] = -5.; b[1] = 13.;
+ foo ();
+ if (c[0] != 32. || c[1] != 30.)
+ __builtin_abort ();
+ return 0;
+}
+
+/* We'd like to see at most one VEC_PERM_EXPR, not one for a blend
+ and one for a permute materialized somewhere else. But addsub
+ pattern recog can likely get in the way here. */
+/* { dg-final { scan-tree-dump-times " \[^ \]\+ = VEC_PERM_EXPR" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr34195.c b/gcc/testsuite/gcc.dg/vect/pr34195.c
new file mode 100644
index 0000000..e36950b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr34195.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+
+#define M 11
+
+struct S
+{
+ float x;
+ float y;
+} pS[100];
+
+float a[1000];
+float b[1000];
+
+void
+foo (int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++)
+ {
+ pS[i].x = 0;
+ pS[i].y = 0;
+
+ for (j = 0; j < M; j++)
+ {
+ pS[i].x += (a[i]+b[i]);
+ pS[i].y += (a[i]-b[i]);
+ }
+ }
+}
+
+/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f16.c
index 35f5c15..8bcd094 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f16.c
@@ -218,7 +218,7 @@ TEST_UNIFORM_ZD (div_h4_f16_x_tied1, svfloat16_t, __fp16,
z0 = svdiv_x (p0, z0, d4))
/*
-** div_h4_f16_x_untied: { xfail *-*-* }
+** div_h4_f16_x_untied:
** mov z0\.h, h4
** fdivr z0\.h, p0/m, z0\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f32.c
index 40cc203..546c61d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f32.c
@@ -218,7 +218,7 @@ TEST_UNIFORM_ZD (div_s4_f32_x_tied1, svfloat32_t, float,
z0 = svdiv_x (p0, z0, d4))
/*
-** div_s4_f32_x_untied: { xfail *-*-* }
+** div_s4_f32_x_untied:
** mov z0\.s, s4
** fdivr z0\.s, p0/m, z0\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f64.c
index 56acbbe..1e24bc26 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/div_f64.c
@@ -218,7 +218,7 @@ TEST_UNIFORM_ZD (div_d4_f64_x_tied1, svfloat64_t, double,
z0 = svdiv_x (p0, z0, d4))
/*
-** div_d4_f64_x_untied: { xfail *-*-* }
+** div_d4_f64_x_untied:
** mov z0\.d, d4
** fdivr z0\.d, p0/m, z0\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f16.c
index 03cc034..e293be6 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f16.c
@@ -239,7 +239,7 @@ TEST_UNIFORM_ZD (divr_h4_f16_x_tied1, svfloat16_t, __fp16,
z0 = svdivr_x (p0, z0, d4))
/*
-** divr_h4_f16_x_untied: { xfail *-*-* }
+** divr_h4_f16_x_untied:
** mov z0\.h, h4
** fdiv z0\.h, p0/m, z0\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f32.c
index c2b65fc..04a7ac4 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f32.c
@@ -239,7 +239,7 @@ TEST_UNIFORM_ZD (divr_s4_f32_x_tied1, svfloat32_t, float,
z0 = svdivr_x (p0, z0, d4))
/*
-** divr_s4_f32_x_untied: { xfail *-*-* }
+** divr_s4_f32_x_untied:
** mov z0\.s, s4
** fdiv z0\.s, p0/m, z0\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f64.c
index 0a72a37..bef1a9b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/divr_f64.c
@@ -239,7 +239,7 @@ TEST_UNIFORM_ZD (divr_d4_f64_x_tied1, svfloat64_t, double,
z0 = svdivr_x (p0, z0, d4))
/*
-** divr_d4_f64_x_untied: { xfail *-*-* }
+** divr_d4_f64_x_untied:
** mov z0\.d, d4
** fdiv z0\.d, p0/m, z0\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f16.c
index 7656f9e..4b31484 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mad_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svmad_x (p0, z1, z0, d4))
/*
-** mad_h4_f16_x_untied: { xfail *-*-* }
+** mad_h4_f16_x_untied:
** mov z0\.h, h4
** fmla z0\.h, p0/m, z1\.h, z2\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f32.c
index dbdd2b9..d5dbc85 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mad_s4_f32_x_tied2, svfloat32_t, float,
z0 = svmad_x (p0, z1, z0, d4))
/*
-** mad_s4_f32_x_untied: { xfail *-*-* }
+** mad_s4_f32_x_untied:
** mov z0\.s, s4
** fmla z0\.s, p0/m, z1\.s, z2\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f64.c
index 9782812..7b5dc22 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mad_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mad_d4_f64_x_tied2, svfloat64_t, double,
z0 = svmad_x (p0, z1, z0, d4))
/*
-** mad_d4_f64_x_untied: { xfail *-*-* }
+** mad_d4_f64_x_untied:
** mov z0\.d, d4
** fmla z0\.d, p0/m, z1\.d, z2\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f16.c
index f22a582..d32ce58 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mla_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svmla_x (p0, z1, z0, d4))
/*
-** mla_h4_f16_x_untied: { xfail *-*-* }
+** mla_h4_f16_x_untied:
** mov z0\.h, h4
** fmad z0\.h, p0/m, z2\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f32.c
index 1d95eb0..d10ba69 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mla_s4_f32_x_tied2, svfloat32_t, float,
z0 = svmla_x (p0, z1, z0, d4))
/*
-** mla_s4_f32_x_untied: { xfail *-*-* }
+** mla_s4_f32_x_untied:
** mov z0\.s, s4
** fmad z0\.s, p0/m, z2\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f64.c
index 74fd292..94c1e0b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mla_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mla_d4_f64_x_tied2, svfloat64_t, double,
z0 = svmla_x (p0, z1, z0, d4))
/*
-** mla_d4_f64_x_untied: { xfail *-*-* }
+** mla_d4_f64_x_untied:
** mov z0\.d, d4
** fmad z0\.d, p0/m, z2\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f16.c
index 87fba3d..b58104d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mls_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svmls_x (p0, z1, z0, d4))
/*
-** mls_h4_f16_x_untied: { xfail *-*-* }
+** mls_h4_f16_x_untied:
** mov z0\.h, h4
** fmsb z0\.h, p0/m, z2\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f32.c
index 04ce1ec..7d6e605 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mls_s4_f32_x_tied2, svfloat32_t, float,
z0 = svmls_x (p0, z1, z0, d4))
/*
-** mls_s4_f32_x_untied: { xfail *-*-* }
+** mls_s4_f32_x_untied:
** mov z0\.s, s4
** fmsb z0\.s, p0/m, z2\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f64.c
index 1e2108a..a6ed28e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mls_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (mls_d4_f64_x_tied2, svfloat64_t, double,
z0 = svmls_x (p0, z1, z0, d4))
/*
-** mls_d4_f64_x_untied: { xfail *-*-* }
+** mls_d4_f64_x_untied:
** mov z0\.d, d4
** fmsb z0\.d, p0/m, z2\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f16.c
index fe11457..894961a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (msb_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svmsb_x (p0, z1, z0, d4))
/*
-** msb_h4_f16_x_untied: { xfail *-*-* }
+** msb_h4_f16_x_untied:
** mov z0\.h, h4
** fmls z0\.h, p0/m, z1\.h, z2\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f32.c
index f7a9f27..0d09159 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (msb_s4_f32_x_tied2, svfloat32_t, float,
z0 = svmsb_x (p0, z1, z0, d4))
/*
-** msb_s4_f32_x_untied: { xfail *-*-* }
+** msb_s4_f32_x_untied:
** mov z0\.s, s4
** fmls z0\.s, p0/m, z1\.s, z2\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f64.c
index e3ff414..52dc396 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/msb_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (msb_d4_f64_x_tied2, svfloat64_t, double,
z0 = svmsb_x (p0, z1, z0, d4))
/*
-** msb_d4_f64_x_untied: { xfail *-*-* }
+** msb_d4_f64_x_untied:
** mov z0\.d, d4
** fmls z0\.d, p0/m, z1\.d, z2\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f16.c
index ce02c3c..b8d6bf5 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f16.c
@@ -303,7 +303,7 @@ TEST_UNIFORM_ZD (mulx_h4_f16_x_tied1, svfloat16_t, __fp16,
z0 = svmulx_x (p0, z0, d4))
/*
-** mulx_h4_f16_x_untied: { xfail *-*-* }
+** mulx_h4_f16_x_untied:
** mov z0\.h, h4
** fmulx z0\.h, p0/m, z0\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f32.c
index e0d3695..b8f5c13 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f32.c
@@ -303,7 +303,7 @@ TEST_UNIFORM_ZD (mulx_s4_f32_x_tied1, svfloat32_t, float,
z0 = svmulx_x (p0, z0, d4))
/*
-** mulx_s4_f32_x_untied: { xfail *-*-* }
+** mulx_s4_f32_x_untied:
** mov z0\.s, s4
** fmulx z0\.s, p0/m, z0\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f64.c
index 6af5703..746cc94 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/mulx_f64.c
@@ -303,7 +303,7 @@ TEST_UNIFORM_ZD (mulx_d4_f64_x_tied1, svfloat64_t, double,
z0 = svmulx_x (p0, z0, d4))
/*
-** mulx_d4_f64_x_untied: { xfail *-*-* }
+** mulx_d4_f64_x_untied:
** mov z0\.d, d4
** fmulx z0\.d, p0/m, z0\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f16.c
index abfe0a0..92e0664 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmad_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svnmad_x (p0, z1, z0, d4))
/*
-** nmad_h4_f16_x_untied: { xfail *-*-* }
+** nmad_h4_f16_x_untied:
** mov z0\.h, h4
** fnmla z0\.h, p0/m, z1\.h, z2\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f32.c
index ab86385..cef731e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmad_s4_f32_x_tied2, svfloat32_t, float,
z0 = svnmad_x (p0, z1, z0, d4))
/*
-** nmad_s4_f32_x_untied: { xfail *-*-* }
+** nmad_s4_f32_x_untied:
** mov z0\.s, s4
** fnmla z0\.s, p0/m, z1\.s, z2\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f64.c
index c236ff5..43b97c0 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmad_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmad_d4_f64_x_tied2, svfloat64_t, double,
z0 = svnmad_x (p0, z1, z0, d4))
/*
-** nmad_d4_f64_x_untied: { xfail *-*-* }
+** nmad_d4_f64_x_untied:
** mov z0\.d, d4
** fnmla z0\.d, p0/m, z1\.d, z2\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f16.c
index f7ac377..75d0ec7 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmla_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svnmla_x (p0, z1, z0, d4))
/*
-** nmla_h4_f16_x_untied: { xfail *-*-* }
+** nmla_h4_f16_x_untied:
** mov z0\.h, h4
** fnmad z0\.h, p0/m, z2\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f32.c
index ef9542d..da594d3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmla_s4_f32_x_tied2, svfloat32_t, float,
z0 = svnmla_x (p0, z1, z0, d4))
/*
-** nmla_s4_f32_x_untied: { xfail *-*-* }
+** nmla_s4_f32_x_untied:
** mov z0\.s, s4
** fnmad z0\.s, p0/m, z2\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f64.c
index 441821f..73f15f4 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmla_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmla_d4_f64_x_tied2, svfloat64_t, double,
z0 = svnmla_x (p0, z1, z0, d4))
/*
-** nmla_d4_f64_x_untied: { xfail *-*-* }
+** nmla_d4_f64_x_untied:
** mov z0\.d, d4
** fnmad z0\.d, p0/m, z2\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f16.c
index 8aa6c75..ccf7e51 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmls_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svnmls_x (p0, z1, z0, d4))
/*
-** nmls_h4_f16_x_untied: { xfail *-*-* }
+** nmls_h4_f16_x_untied:
** mov z0\.h, h4
** fnmsb z0\.h, p0/m, z2\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f32.c
index 42ea13f..10d3450 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmls_s4_f32_x_tied2, svfloat32_t, float,
z0 = svnmls_x (p0, z1, z0, d4))
/*
-** nmls_s4_f32_x_untied: { xfail *-*-* }
+** nmls_s4_f32_x_untied:
** mov z0\.s, s4
** fnmsb z0\.s, p0/m, z2\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f64.c
index 994c2a7..bf2a441 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmls_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmls_d4_f64_x_tied2, svfloat64_t, double,
z0 = svnmls_x (p0, z1, z0, d4))
/*
-** nmls_d4_f64_x_untied: { xfail *-*-* }
+** nmls_d4_f64_x_untied:
** mov z0\.d, d4
** fnmsb z0\.d, p0/m, z2\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f16.c
index c114014..5311ceb 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f16.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmsb_h4_f16_x_tied2, svfloat16_t, __fp16,
z0 = svnmsb_x (p0, z1, z0, d4))
/*
-** nmsb_h4_f16_x_untied: { xfail *-*-* }
+** nmsb_h4_f16_x_untied:
** mov z0\.h, h4
** fnmls z0\.h, p0/m, z1\.h, z2\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f32.c
index c2204e0..6f1407a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f32.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmsb_s4_f32_x_tied2, svfloat32_t, float,
z0 = svnmsb_x (p0, z1, z0, d4))
/*
-** nmsb_s4_f32_x_untied: { xfail *-*-* }
+** nmsb_s4_f32_x_untied:
** mov z0\.s, s4
** fnmls z0\.s, p0/m, z1\.s, z2\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f64.c
index 56592d3..5e4e1dd 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/nmsb_f64.c
@@ -281,7 +281,7 @@ TEST_UNIFORM_ZD (nmsb_d4_f64_x_tied2, svfloat64_t, double,
z0 = svnmsb_x (p0, z1, z0, d4))
/*
-** nmsb_d4_f64_x_untied: { xfail *-*-* }
+** nmsb_d4_f64_x_untied:
** mov z0\.d, d4
** fnmls z0\.d, p0/m, z1\.d, z2\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f16.c
index bf4a0ab..48a5746 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f16.c
@@ -336,7 +336,7 @@ TEST_UNIFORM_ZD (sub_h4_f16_x_tied1, svfloat16_t, __fp16,
z0 = svsub_x (p0, z0, d4))
/*
-** sub_h4_f16_x_untied: { xfail *-*-* }
+** sub_h4_f16_x_untied:
** mov z0\.h, h4
** fsubr z0\.h, p0/m, z0\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f32.c
index 05be52b..32d57be 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f32.c
@@ -336,7 +336,7 @@ TEST_UNIFORM_ZD (sub_s4_f32_x_tied1, svfloat32_t, float,
z0 = svsub_x (p0, z0, d4))
/*
-** sub_s4_f32_x_untied: { xfail *-*-* }
+** sub_s4_f32_x_untied:
** mov z0\.s, s4
** fsubr z0\.s, p0/m, z0\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f64.c
index 2179382..cdc2558 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sub_f64.c
@@ -336,7 +336,7 @@ TEST_UNIFORM_ZD (sub_d4_f64_x_tied1, svfloat64_t, double,
z0 = svsub_x (p0, z0, d4))
/*
-** sub_d4_f64_x_untied: { xfail *-*-* }
+** sub_d4_f64_x_untied:
** mov z0\.d, d4
** fsubr z0\.d, p0/m, z0\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f16.c
index e14357d..6929b28 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f16.c
@@ -285,7 +285,7 @@ TEST_UNIFORM_ZD (subr_h4_f16_x_tied1, svfloat16_t, __fp16,
z0 = svsubr_x (p0, z0, d4))
/*
-** subr_h4_f16_x_untied: { xfail *-*-* }
+** subr_h4_f16_x_untied:
** mov z0\.h, h4
** fsub z0\.h, p0/m, z0\.h, z1\.h
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f32.c
index 98dc7ad..5bf90a3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f32.c
@@ -285,7 +285,7 @@ TEST_UNIFORM_ZD (subr_s4_f32_x_tied1, svfloat32_t, float,
z0 = svsubr_x (p0, z0, d4))
/*
-** subr_s4_f32_x_untied: { xfail *-*-* }
+** subr_s4_f32_x_untied:
** mov z0\.s, s4
** fsub z0\.s, p0/m, z0\.s, z1\.s
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f64.c
index 81f1112..7091c40 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/subr_f64.c
@@ -285,7 +285,7 @@ TEST_UNIFORM_ZD (subr_d4_f64_x_tied1, svfloat64_t, double,
z0 = svsubr_x (p0, z0, d4))
/*
-** subr_d4_f64_x_untied: { xfail *-*-* }
+** subr_d4_f64_x_untied:
** mov z0\.d, d4
** fsub z0\.d, p0/m, z0\.d, z1\.d
** ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
new file mode 100644
index 0000000..b43fcf0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <arm_sve.h>
+
+unsigned int
+foo (unsigned int x)
+{
+ unsigned long tmp = x;
+ tmp += svcntb ();
+ x = tmp;
+ return x - svcntb ();
+}
+
+/* { dg-final { scan-tree-dump-not { POLY_INT_CST } optimized } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/pr98435.c b/gcc/testsuite/gcc.target/arm/simd/pr98435.c
new file mode 100644
index 0000000..0af8633
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/pr98435.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
+/* { dg-add-options arm_v8_2a_bf16_neon } */
+/* { dg-additional-options "-mfloat-abi=softfp -march=armv8.2-a+bf16+fp16" } */
+
+#include <arm_neon.h>
+
+bfloat16x4_t f (bfloat16_t a)
+{
+ return (bfloat16x4_t) {a, a, a, a};
+}
+
+/* { dg-final { scan-assembler {\tvdup.16\td[0-9]+, r0} } } */
+/* { dg-final { scan-assembler {\tvmov\tr0, r1, d[0-9]+} } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr101286.c b/gcc/testsuite/gcc.target/i386/avx2-pr101286.c
new file mode 100644
index 0000000..81917bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx2-pr101286.c
@@ -0,0 +1,11 @@
+/* PR target/101286 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-mavx2" } */
+
+typedef __attribute__((__vector_size__ (2 * sizeof (__int128)))) __int128 V;
+
+V
+foo (void)
+{
+ return (V){(__int128) 1 << 64 | 1, (__int128) 1 << 64 | 1};
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-1.c b/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-1.c
index 0563e69..a2664d8 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-1.c
@@ -2,8 +2,11 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mavx512f -mavx512dq" } */
/* { dg-additional-options "-mdynamic-no-pic" { target { *-*-darwin* && ia32 } } }
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 5 } } */
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to16\\\}" 5 } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 5 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to16\\\}" 2 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %zmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %zmm\[0-9\]+" 3 { target { ! ia32 } } } } */
typedef int v16si __attribute__ ((vector_size (64)));
typedef long long v8di __attribute__ ((vector_size (64)));
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-5.c b/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-5.c
index ffbe959..477f9ca 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-5.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-broadcast-pr87767-5.c
@@ -2,8 +2,9 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mavx512f" } */
/* { dg-additional-options "-mdynamic-no-pic" { target { *-*-darwin* && ia32 } } }
-/* { dg-final { scan-assembler-times "\[^n\n\]*\\\{1to8\\\}" 4 } } */
-/* { dg-final { scan-assembler-times "\[^n\n\]*\\\{1to16\\\}" 4 } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 4 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %zmm\[0-9\]+" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %zmm\[0-9\]+" 4 { target { ! ia32 } } } } */
typedef int v16si __attribute__ ((vector_size (64)));
typedef long long v8di __attribute__ ((vector_size (64)));
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXpd.c b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXpd.c
new file mode 100644
index 0000000..734f9e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXpd.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O3 -mfma -save-temps -mavx512f -mprefer-vector-width=512" } */
+
+#include "fma-check.h"
+void __attribute__((noipa))
+check_fmaddsub (double * __restrict a, double *b, double *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[8*i + 0] = b[8*i + 0] * c[8*i + 0] - a[8*i + 0];
+ a[8*i + 1] = b[8*i + 1] * c[8*i + 1] + a[8*i + 1];
+ a[8*i + 2] = b[8*i + 2] * c[8*i + 2] - a[8*i + 2];
+ a[8*i + 3] = b[8*i + 3] * c[8*i + 3] + a[8*i + 3];
+ a[8*i + 4] = b[8*i + 4] * c[8*i + 4] - a[8*i + 4];
+ a[8*i + 5] = b[8*i + 5] * c[8*i + 5] + a[8*i + 5];
+ a[8*i + 6] = b[8*i + 6] * c[8*i + 6] - a[8*i + 6];
+ a[8*i + 7] = b[8*i + 7] * c[8*i + 7] + a[8*i + 7];
+ }
+}
+
+static void
+fma_test (void)
+{
+ if (!__builtin_cpu_supports ("avx512f"))
+ return;
+ double a[8], b[8], c[8];
+ for (int i = 0; i < 8; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 1);
+ const double d[8] = { 0., 22., 82., 192., 332., 530., 750., 1036.};
+ for (int i = 0; i < 8; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler {(?n)fmaddsub...pd[ \t].*%zmm[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXps.c b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXps.c
new file mode 100644
index 0000000..ae196c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmaddsubXXXps.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O3 -mavx512f -mprefer-vector-width=512 -save-temps" } */
+
+#include "fma-check.h"
+void __attribute__((noipa))
+check_fmaddsub (float * __restrict a, float *b, float *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[16*i + 0] = b[16*i + 0] * c[16*i + 0] - a[16*i + 0];
+ a[16*i + 1] = b[16*i + 1] * c[16*i + 1] + a[16*i + 1];
+ a[16*i + 2] = b[16*i + 2] * c[16*i + 2] - a[16*i + 2];
+ a[16*i + 3] = b[16*i + 3] * c[16*i + 3] + a[16*i + 3];
+ a[16*i + 4] = b[16*i + 4] * c[16*i + 4] - a[16*i + 4];
+ a[16*i + 5] = b[16*i + 5] * c[16*i + 5] + a[16*i + 5];
+ a[16*i + 6] = b[16*i + 6] * c[16*i + 6] - a[16*i + 6];
+ a[16*i + 7] = b[16*i + 7] * c[16*i + 7] + a[16*i + 7];
+ a[16*i + 8] = b[16*i + 8] * c[16*i + 8] - a[16*i + 8];
+ a[16*i + 9] = b[16*i + 9] * c[16*i + 9] + a[16*i + 9];
+ a[16*i + 10] = b[16*i + 10] * c[16*i + 10] - a[16*i + 10];
+ a[16*i + 11] = b[16*i + 11] * c[16*i + 11] + a[16*i + 11];
+ a[16*i + 12] = b[16*i + 12] * c[16*i + 12] - a[16*i + 12];
+ a[16*i + 13] = b[16*i + 13] * c[16*i + 13] + a[16*i + 13];
+ a[16*i + 14] = b[16*i + 14] * c[16*i + 14] - a[16*i + 14];
+ a[16*i + 15] = b[16*i + 15] * c[16*i + 15] + a[16*i + 15];
+ }
+}
+
+static void
+fma_test (void)
+{
+ if (!__builtin_cpu_supports ("avx512f"))
+ return;
+ float a[16], b[16], c[16];
+ for (int i = 0; i < 16; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 1);
+ const float d[16] = { 0., 22., 82., 192., 332., 530., 750., 1036.,
+ 1336, 1710., 2090., 2552., 3012., 3562., 4102., 4740.};
+ for (int i = 0; i < 16; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler {(?n)fmaddsub...ps[ \t].*%zmm[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXpd.c b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXpd.c
new file mode 100644
index 0000000..cde76db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXpd.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O3 -mavx512f -mprefer-vector-width=512 -save-temps" } */
+
+#include "fma-check.h"
+void __attribute__((noipa))
+check_fmaddsub (double * __restrict a, double *b, double *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[8*i + 0] = b[8*i + 0] * c[8*i + 0] + a[8*i + 0];
+ a[8*i + 1] = b[8*i + 1] * c[8*i + 1] - a[8*i + 1];
+ a[8*i + 2] = b[8*i + 2] * c[8*i + 2] + a[8*i + 2];
+ a[8*i + 3] = b[8*i + 3] * c[8*i + 3] - a[8*i + 3];
+ a[8*i + 4] = b[8*i + 4] * c[8*i + 4] + a[8*i + 4];
+ a[8*i + 5] = b[8*i + 5] * c[8*i + 5] - a[8*i + 5];
+ a[8*i + 6] = b[8*i + 6] * c[8*i + 6] + a[8*i + 6];
+ a[8*i + 7] = b[8*i + 7] * c[8*i + 7] - a[8*i + 7];
+ }
+}
+
+static void
+fma_test (void)
+{
+ if (!__builtin_cpu_supports ("avx512f"))
+ return;
+ double a[8], b[8], c[8];
+ for (int i = 0; i < 8; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 1);
+ const double d[8] = { 0., 20., 86., 186., 340., 520., 762., 1022.};
+ for (int i = 0; i < 8; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler {(?n)fmsubadd...pd[ \t].*%zmm[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXps.c b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXps.c
new file mode 100644
index 0000000..59de39f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vect-fmsubaddXXXps.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O3 -mavx512f -mprefer-vector-width=512 -save-temps" } */
+
+#include "fma-check.h"
+void __attribute__((noipa))
+check_fmaddsub (float * __restrict a, float *b, float *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[16*i + 0] = b[16*i + 0] * c[16*i + 0] + a[16*i + 0];
+ a[16*i + 1] = b[16*i + 1] * c[16*i + 1] - a[16*i + 1];
+ a[16*i + 2] = b[16*i + 2] * c[16*i + 2] + a[16*i + 2];
+ a[16*i + 3] = b[16*i + 3] * c[16*i + 3] - a[16*i + 3];
+ a[16*i + 4] = b[16*i + 4] * c[16*i + 4] + a[16*i + 4];
+ a[16*i + 5] = b[16*i + 5] * c[16*i + 5] - a[16*i + 5];
+ a[16*i + 6] = b[16*i + 6] * c[16*i + 6] + a[16*i + 6];
+ a[16*i + 7] = b[16*i + 7] * c[16*i + 7] - a[16*i + 7];
+ a[16*i + 8] = b[16*i + 8] * c[16*i + 8] + a[16*i + 8];
+ a[16*i + 9] = b[16*i + 9] * c[16*i + 9] - a[16*i + 9];
+ a[16*i + 10] = b[16*i + 10] * c[16*i + 10] + a[16*i + 10];
+ a[16*i + 11] = b[16*i + 11] * c[16*i + 11] - a[16*i + 11];
+ a[16*i + 12] = b[16*i + 12] * c[16*i + 12] + a[16*i + 12];
+ a[16*i + 13] = b[16*i + 13] * c[16*i + 13] - a[16*i + 13];
+ a[16*i + 14] = b[16*i + 14] * c[16*i + 14] + a[16*i + 14];
+ a[16*i + 15] = b[16*i + 15] * c[16*i + 15] - a[16*i + 15];
+ }
+}
+
+static void
+fma_test (void)
+{
+ if (!__builtin_cpu_supports ("avx512f"))
+ return;
+ float a[16], b[16], c[16];
+ for (int i = 0; i < 16; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 1);
+ const float d[16] = { 0., 20., 86., 186., 340., 520., 762., 1022.,
+ 1352, 1692., 2110., 2530., 3036., 3536., 4130., 4710.};
+ for (int i = 0; i < 16; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler {(?n)fmsubadd...ps[ \t].*%zmm[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f_cond_move.c b/gcc/testsuite/gcc.target/i386/avx512f_cond_move.c
index 99a89f5..ca49a58 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f_cond_move.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f_cond_move.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -mavx512f" } */
-/* { dg-final { scan-assembler-times "(?:vpblendmd|vmovdqa32)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 8 } } */
+/* { dg-options "-O3 -mavx512f -mprefer-vector-width=512" } */
+/* { dg-final { scan-assembler-times "(?:vpbroadcastd|vmovdqa32)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 8 } } */
unsigned int x[128];
int y[128];
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-1.c
index c06369d..f8eb99f 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-1.c
@@ -2,9 +2,15 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mavx512f -mavx512vl -mavx512dq" } */
/* { dg-additional-options "-mdynamic-no-pic" { target { *-*-darwin* && ia32 } } }
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to2\\\}" 5 } } */
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to4\\\}" 10 } } */
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 5 } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to2\\\}" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to4\\\}" 4 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to2\\\}" 5 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to4\\\}" 7 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 2 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %xmm\[0-9\]+" 3 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %ymm\[0-9\]+" 3 { target { ! ia32 } } } } */
typedef int v4si __attribute__ ((vector_size (16)));
typedef int v8si __attribute__ ((vector_size (32)));
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-5.c b/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-5.c
index 4998a9b..32f6ac8 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-5.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-broadcast-pr87767-5.c
@@ -2,9 +2,12 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mavx512f -mavx512vl" } */
/* { dg-additional-options "-mdynamic-no-pic" { target { *-*-darwin* && ia32 } } }
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to2\\\}" 4 } } */
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to4\\\}" 8 } } */
-/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to8\\\}" 4 } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to2\\\}" 4 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "\[^\n\]*\\\{1to4\\\}" 4 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %xmm\[0-9\]+" 4 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %ymm\[0-9\]+" 4 { target { ! ia32 } } } } */
typedef int v4si __attribute__ ((vector_size (16)));
typedef int v8si __attribute__ ((vector_size (32)));
diff --git a/gcc/testsuite/gcc.target/i386/divmod-9.c b/gcc/testsuite/gcc.target/i386/divmod-9.c
new file mode 100644
index 0000000..1515e69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/divmod-9.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int foo (int x)
+{
+ return 100/x;
+}
+
+int bar(int x)
+{
+ return -100/x;
+}
+/* { dg-final { scan-assembler-not "(cltd|cdq)" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdec128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdec128kl.c
index d134612..71111c3 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesdec128kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdec128kl.c
@@ -2,8 +2,10 @@
/* { dg-options "-mkl -O2" } */
/* { dg-final { scan-assembler "movdqa\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
/* { dg-final { scan-assembler "aesdec128kl\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdec256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdec256kl.c
index 34736d2..30189d6 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesdec256kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdec256kl.c
@@ -2,8 +2,10 @@
/* { dg-options "-mkl -O2" } */
/* { dg-final { scan-assembler "movdqa\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
/* { dg-final { scan-assembler "aesdec256kl\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c
index d23cf4b..93806e5 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c
@@ -9,6 +9,7 @@
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*96\[^\\n\\r\]*, %xmm6" } } */
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*112\[^\\n\\r\]*, %xmm7" } } */
/* { dg-final { scan-assembler "aesdecwide128kl\[ \\t\]+\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm1,\[^\\n\\r\]*16\[^\\n\\r\]*" } } */
@@ -18,6 +19,14 @@
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c
index 44c3252..f9ccc82 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c
@@ -9,6 +9,7 @@
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*96\[^\\n\\r\]*, %xmm6" } } */
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*112\[^\\n\\r\]*, %xmm7" } } */
/* { dg-final { scan-assembler "aesdecwide256kl\[ \\t\]+\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm1,\[^\\n\\r\]*16\[^\\n\\r\]*" } } */
@@ -18,6 +19,14 @@
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesenc128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesenc128kl.c
index 9ff4836..61a9cc2 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesenc128kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesenc128kl.c
@@ -2,8 +2,10 @@
/* { dg-options "-mkl -O2" } */
/* { dg-final { scan-assembler "movdqa\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
/* { dg-final { scan-assembler "aesenc128kl\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesenc256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesenc256kl.c
index 1c5e076..f8e6bb7 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesenc256kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesenc256kl.c
@@ -2,8 +2,10 @@
/* { dg-options "-mkl -O2" } */
/* { dg-final { scan-assembler "movdqa\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
/* { dg-final { scan-assembler "aesenc256kl\[ \\t\]+\[^\\n\\r\]*, %xmm0" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c
index 9fb9c49..c0fcd28 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c
@@ -9,6 +9,7 @@
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*96\[^\\n\\r\]*, %xmm6" } } */
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*112\[^\\n\\r\]*, %xmm7" } } */
/* { dg-final { scan-assembler "aesencwide128kl\[ \\t\]+\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm1,\[^\\n\\r\]*16\[^\\n\\r\]*" } } */
@@ -18,6 +19,14 @@
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c
index 125a787..31463a8 100644
--- a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c
+++ b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c
@@ -9,6 +9,7 @@
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*96\[^\\n\\r\]*, %xmm6" } } */
/* { dg-final { scan-assembler "movdqu\[ \\t\]+\[^\\n\\r\]*112\[^\\n\\r\]*, %xmm7" } } */
/* { dg-final { scan-assembler "aesencwide256kl\[ \\t\]+\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "j\[ez\]" } } */
/* { dg-final { scan-assembler "sete" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm0,\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm1,\[^\\n\\r\]*16\[^\\n\\r\]*" } } */
@@ -18,6 +19,14 @@
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */
/* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */
+/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-1.c b/gcc/testsuite/gcc.target/i386/pr100865-1.c
new file mode 100644
index 0000000..6c3097f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+extern char *dst;
+
+void
+foo (void)
+{
+ __builtin_memset (dst, 3, 16);
+}
+
+/* { dg-final { scan-assembler-times "movdqa\[ \\t\]+\[^\n\]*%xmm" 1 } } */
+/* { dg-final { scan-assembler-times "movups\[\\t \]%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-10a.c b/gcc/testsuite/gcc.target/i386/pr100865-10a.c
new file mode 100644
index 0000000..7ffc19e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-10a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern __int128 array[16];
+
+#define MK_CONST128_BROADCAST(A) \
+ ((((unsigned __int128) (unsigned char) A) << 120) \
+ | (((unsigned __int128) (unsigned char) A) << 112) \
+ | (((unsigned __int128) (unsigned char) A) << 104) \
+ | (((unsigned __int128) (unsigned char) A) << 96) \
+ | (((unsigned __int128) (unsigned char) A) << 88) \
+ | (((unsigned __int128) (unsigned char) A) << 80) \
+ | (((unsigned __int128) (unsigned char) A) << 72) \
+ | (((unsigned __int128) (unsigned char) A) << 64) \
+ | (((unsigned __int128) (unsigned char) A) << 56) \
+ | (((unsigned __int128) (unsigned char) A) << 48) \
+ | (((unsigned __int128) (unsigned char) A) << 40) \
+ | (((unsigned __int128) (unsigned char) A) << 32) \
+ | (((unsigned __int128) (unsigned char) A) << 24) \
+ | (((unsigned __int128) (unsigned char) A) << 16) \
+ | (((unsigned __int128) (unsigned char) A) << 8) \
+ | ((unsigned __int128) (unsigned char) A) )
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = MK_CONST128_BROADCAST (0x1f);
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-10b.c b/gcc/testsuite/gcc.target/i386/pr100865-10b.c
new file mode 100644
index 0000000..edf5276
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-10b.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-10a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-11a.c b/gcc/testsuite/gcc.target/i386/pr100865-11a.c
new file mode 100644
index 0000000..04ce166
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-11a.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern __int128 array[16];
+
+#define MK_CONST128_BROADCAST(A) \
+ ((((unsigned __int128) (unsigned long long) A) << 64) \
+ | ((unsigned __int128) (unsigned long long) A) )
+
+#define MK_CONST128_BROADCAST_SIGNED(A) \
+ ((__int128) MK_CONST128_BROADCAST (A))
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = MK_CONST128_BROADCAST_SIGNED (-0x1ffffffffLL);
+}
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "(?:vpbroadcastq|vpunpcklqdq)\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-11b.c b/gcc/testsuite/gcc.target/i386/pr100865-11b.c
new file mode 100644
index 0000000..12d55b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-11b.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-11a.c"
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-11c.c b/gcc/testsuite/gcc.target/i386/pr100865-11c.c
new file mode 100644
index 0000000..de56c84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-11c.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+#include "pr100865-11a.c"
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "vpunpcklqdq\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-12a.c b/gcc/testsuite/gcc.target/i386/pr100865-12a.c
new file mode 100644
index 0000000..d4833d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-12a.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern __int128 array[16];
+
+#define MK_CONST128_BROADCAST(A) \
+ ((((unsigned __int128) (unsigned long long) A) << 64) \
+ | ((unsigned __int128) (unsigned long long) A) )
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = MK_CONST128_BROADCAST (0x1ffffffffLL);
+}
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "(?:vpbroadcastq|vpunpcklqdq)\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-12b.c b/gcc/testsuite/gcc.target/i386/pr100865-12b.c
new file mode 100644
index 0000000..63a5629
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-12b.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-12a.c"
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-12c.c b/gcc/testsuite/gcc.target/i386/pr100865-12c.c
new file mode 100644
index 0000000..77415f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-12c.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+#include "pr100865-12a.c"
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "vpunpcklqdq\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-2.c b/gcc/testsuite/gcc.target/i386/pr100865-2.c
new file mode 100644
index 0000000..17efe2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char *dst;
+
+void
+foo (void)
+{
+ __builtin_memset (dst, 3, 16);
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-3.c b/gcc/testsuite/gcc.target/i386/pr100865-3.c
new file mode 100644
index 0000000..b6dbcf7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=skylake-avx512" } */
+
+extern char *dst;
+
+void
+foo (void)
+{
+ __builtin_memset (dst, 3, 16);
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-not "vpbroadcastb\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-4a.c b/gcc/testsuite/gcc.target/i386/pr100865-4a.c
new file mode 100644
index 0000000..f558835
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-4a.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%xmm\[0-9\]+, " 4 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-4b.c b/gcc/testsuite/gcc.target/i386/pr100865-4b.c
new file mode 100644
index 0000000..f41e614
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-4b.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -march=skylake-avx512" } */
+
+#include "pr100865-4a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%xmm\[0-9\]+, " 4 } } */
+/* { dg-final { scan-assembler-not "vpbroadcastb\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-5a.c b/gcc/testsuite/gcc.target/i386/pr100865-5a.c
new file mode 100644
index 0000000..4149797
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-5a.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern short array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastw\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 4 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-5b.c b/gcc/testsuite/gcc.target/i386/pr100865-5b.c
new file mode 100644
index 0000000..ded41b68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-5b.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-5a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastw\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu16\[\\t \]%ymm\[0-9\]+, " 4 } } */
+/* { dg-final { scan-assembler-not "vpbroadcastw\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-6a.c b/gcc/testsuite/gcc.target/i386/pr100865-6a.c
new file mode 100644
index 0000000..3fde549
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-6a.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern int array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 8 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-6b.c b/gcc/testsuite/gcc.target/i386/pr100865-6b.c
new file mode 100644
index 0000000..44e74c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-6b.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-6a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 8 } } */
+/* { dg-final { scan-assembler-not "vpbroadcastd\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-6c.c b/gcc/testsuite/gcc.target/i386/pr100865-6c.c
new file mode 100644
index 0000000..46d3103
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-6c.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+extern int array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vbroadcastss" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 8 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-7a.c b/gcc/testsuite/gcc.target/i386/pr100865-7a.c
new file mode 100644
index 0000000..f6f2be9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-7a.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern long long int array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+\[^\n\]*, %ymm\[0-9\]+" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 16 } } */
+/* { dg-final { scan-assembler-not "vpbroadcastq" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "vmovdqa" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-7b.c b/gcc/testsuite/gcc.target/i386/pr100865-7b.c
new file mode 100644
index 0000000..0a68820
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-7b.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-7a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+%r\[^\n\]*, %ymm\[0-9\]+" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq\[\\t \]+\[^\n\]*, %ymm\[0-9\]+" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 16 } } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-7c.c b/gcc/testsuite/gcc.target/i386/pr100865-7c.c
new file mode 100644
index 0000000..4d50bb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-7c.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+extern long long int array[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = -45;
+}
+
+/* { dg-final { scan-assembler-times "vbroadcastsd" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 16 } } */
+/* { dg-final { scan-assembler-not "vbroadcastsd" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "vmovdqa" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-8a.c b/gcc/testsuite/gcc.target/i386/pr100865-8a.c
new file mode 100644
index 0000000..544a14d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-8a.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern __int128 array[16];
+
+#define MK_CONST128_BROADCAST(A) \
+ ((((unsigned __int128) (unsigned int) A) << 96) \
+ | (((unsigned __int128) (unsigned int) A) << 64) \
+ | (((unsigned __int128) (unsigned int) A) << 32) \
+ | ((unsigned __int128) (unsigned int) A) )
+
+#define MK_CONST128_BROADCAST_SIGNED(A) \
+ ((__int128) MK_CONST128_BROADCAST (A))
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = MK_CONST128_BROADCAST_SIGNED (-45);
+}
+
+/* { dg-final { scan-assembler-times "(?:vpbroadcastd|vpshufd)\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-8b.c b/gcc/testsuite/gcc.target/i386/pr100865-8b.c
new file mode 100644
index 0000000..99a10ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-8b.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-8a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-8c.c b/gcc/testsuite/gcc.target/i386/pr100865-8c.c
new file mode 100644
index 0000000..efee048
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-8c.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+#include "pr100865-8a.c"
+
+/* { dg-final { scan-assembler-times "vpshufd\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-9a.c b/gcc/testsuite/gcc.target/i386/pr100865-9a.c
new file mode 100644
index 0000000..45d0e0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-9a.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake" } */
+
+extern __int128 array[16];
+
+#define MK_CONST128_BROADCAST(A) \
+ ((((unsigned __int128) (unsigned short) A) << 112) \
+ | (((unsigned __int128) (unsigned short) A) << 96) \
+ | (((unsigned __int128) (unsigned short) A) << 80) \
+ | (((unsigned __int128) (unsigned short) A) << 64) \
+ | (((unsigned __int128) (unsigned short) A) << 48) \
+ | (((unsigned __int128) (unsigned short) A) << 32) \
+ | (((unsigned __int128) (unsigned short) A) << 16) \
+ | ((unsigned __int128) (unsigned short) A) )
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < sizeof (array) / sizeof (array[0]); i++)
+ array[i] = MK_CONST128_BROADCAST (0x1fff);
+}
+
+/* { dg-final { scan-assembler-times "vpbroadcastw\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-9b.c b/gcc/testsuite/gcc.target/i386/pr100865-9b.c
new file mode 100644
index 0000000..1469624
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-9b.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake-avx512" } */
+
+#include "pr100865-9a.c"
+
+/* { dg-final { scan-assembler-times "vpbroadcastw\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100865-9c.c b/gcc/testsuite/gcc.target/i386/pr100865-9c.c
new file mode 100644
index 0000000..e6f2590
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100865-9c.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O3 -march=skylake -mno-avx2" } */
+
+#include "pr100865-9a.c"
+
+/* { dg-final { scan-assembler-times "vpshufd\[\\t \]+\[^\n\]*, %xmm\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]%xmm\[0-9\]+, " 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr101044.c b/gcc/testsuite/gcc.target/i386/pr101044.c
new file mode 100644
index 0000000..03df86d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101044.c
@@ -0,0 +1,9 @@
+/* PR target/101044 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic" } */
+/* { dg-final { scan-assembler-times "neg" 1 } } */
+
+int foo (int x)
+{
+ return (x < 0) ? x : -x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr92658-avx512vl.c b/gcc/testsuite/gcc.target/i386/pr92658-avx512vl.c
index a9f7d7e..7ff9c19 100644
--- a/gcc/testsuite/gcc.target/i386/pr92658-avx512vl.c
+++ b/gcc/testsuite/gcc.target/i386/pr92658-avx512vl.c
@@ -122,8 +122,7 @@ truncdb_128 (v16qi * dst, v4si * __restrict src)
}
/* { dg-final { scan-assembler-times "vpmovqd" 2 } } */
-/* { dg-final { scan-assembler-times "vpmovqw" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "vpmovqw" 2 } } */
/* { dg-final { scan-assembler-times "vpmovqb" 2 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "vpmovdw" 1 } } */
-/* { dg-final { scan-assembler-times "vpmovdw" 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "vpmovdw" 2 } } */
/* { dg-final { scan-assembler-times "vpmovdb" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-1a.c b/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-1a.c
new file mode 100644
index 0000000..e2a67a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-1a.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse4.1 -O2" } */
+/* { dg-final { scan-assembler-times {(?n)v?pcmpeq[bwd]} 2 } } */
+/* { dg-final { scan-assembler-times {(?n)v?p?blendv} 2 } } */
+
+typedef char v4qi __attribute__ ((vector_size (4)));
+typedef short v2hi __attribute__ ((vector_size (4)));
+
+#define FOO(VTYPE, TYPE) \
+ VTYPE \
+ __attribute__ ((noipa)) \
+ foo_##VTYPE (VTYPE a, TYPE b, unsigned int c) \
+ { \
+ a[c] = b; \
+ return a; \
+ } \
+
+FOO (v4qi, char);
+
+FOO (v2hi, short);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-2a.c b/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-2a.c
new file mode 100644
index 0000000..5a945be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-vec-set-2a.c
@@ -0,0 +1,44 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O2 -msse4.1" } */
+
+
+#ifndef CHECK
+#define CHECK "sse4_1-check.h"
+#endif
+
+#ifndef TEST
+#define TEST sse4_1_test
+#endif
+
+#include CHECK
+
+#include "sse4_1-vec-set-1a.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 (v4qi, char, 4, 2);
+ CALC_TEST (v2hi, short, 2, 1);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXpd.c b/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXpd.c
new file mode 100644
index 0000000..b30d107
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXpd.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fma } */
+/* { dg-options "-O3 -mfma -save-temps" } */
+
+#include "fma-check.h"
+
+void __attribute__((noipa))
+check_fmaddsub (double * __restrict a, double *b, double *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[2*i + 0] = b[2*i + 0] * c[2*i + 0] - a[2*i + 0];
+ a[2*i + 1] = b[2*i + 1] * c[2*i + 1] + a[2*i + 1];
+ }
+}
+
+static void
+fma_test (void)
+{
+ double a[4], b[4], c[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 2);
+ const double d[4] = { 0., 22., 82., 192. };
+ for (int i = 0; i < 4; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler "fmaddsub...pd" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXps.c b/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXps.c
new file mode 100644
index 0000000..cd2af87
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-fmaddsubXXXps.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fma } */
+/* { dg-options "-O3 -mfma -save-temps" } */
+
+#include "fma-check.h"
+
+void __attribute__((noipa))
+check_fmaddsub (float * __restrict a, float *b, float *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[2*i + 0] = b[2*i + 0] * c[2*i + 0] - a[2*i + 0];
+ a[2*i + 1] = b[2*i + 1] * c[2*i + 1] + a[2*i + 1];
+ }
+}
+
+static void
+fma_test (void)
+{
+ float a[4], b[4], c[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmaddsub (a, b, c, 2);
+ const float d[4] = { 0., 22., 82., 192. };
+ for (int i = 0; i < 4; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler "fmaddsub...ps" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXpd.c b/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXpd.c
new file mode 100644
index 0000000..7ca2a27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXpd.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fma } */
+/* { dg-options "-O3 -mfma -save-temps" } */
+
+#include "fma-check.h"
+
+void __attribute__((noipa))
+check_fmsubadd (double * __restrict a, double *b, double *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[2*i + 0] = b[2*i + 0] * c[2*i + 0] + a[2*i + 0];
+ a[2*i + 1] = b[2*i + 1] * c[2*i + 1] - a[2*i + 1];
+ }
+}
+
+static void
+fma_test (void)
+{
+ double a[4], b[4], c[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmsubadd (a, b, c, 2);
+ const double d[4] = { 0., 20., 86., 186. };
+ for (int i = 0; i < 4; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler "fmsubadd...pd" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXps.c b/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXps.c
new file mode 100644
index 0000000..9ddd0e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-fmsubaddXXXps.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fma } */
+/* { dg-options "-O3 -mfma -save-temps" } */
+
+#include "fma-check.h"
+
+void __attribute__((noipa))
+check_fmsubadd (float * __restrict a, float *b, float *c, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ a[2*i + 0] = b[2*i + 0] * c[2*i + 0] + a[2*i + 0];
+ a[2*i + 1] = b[2*i + 1] * c[2*i + 1] - a[2*i + 1];
+ }
+}
+
+static void
+fma_test (void)
+{
+ float a[4], b[4], c[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ a[i] = i;
+ b[i] = 3*i;
+ c[i] = 7*i;
+ }
+ check_fmsubadd (a, b, c, 2);
+ const float d[4] = { 0., 20., 86., 186. };
+ for (int i = 0; i < 4; ++i)
+ if (a[i] != d[i])
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler "fmsubadd...ps" } } */
diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c
index bf22f06..6a9f86a 100644
--- a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c
+++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c
@@ -1,10 +1,15 @@
/* { dg-do compile } */
-/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips -fno-inline -fipa-ra -mcompact-branches=never" } */
+/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips -fipa-ra -mcompact-branches=never" } */
/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */
-static int foo (void* p) { __asm__ (""::"r"(p):"$t0"); return 0; }
+static int __attribute__((noinline))
+foo (void* p)
+{
+ __asm__ (""::"r"(p):"$t0");
+ return 0;
+}
-static int bar (void* p) { return 1; }
+__attribute__((noinline)) static int bar (void* p) { return 1; }
int
test (void* p)
diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c
index 805b31a..5093741 100644
--- a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c
+++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c
@@ -1,10 +1,10 @@
/* { dg-do compile } */
-/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips -fno-inline -fipa-ra -mcompact-branches=never" } */
+/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips -fipa-ra -mcompact-branches=never" } */
/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */
-static int foo (void* p) { return 0; }
+__attribute__((noinline)) static int foo (void* p) { return 0; }
-static int bar (void* p) { return 1; }
+__attribute__((noinline)) static int bar (void* p) { return 1; }
int
test (void* p)
diff --git a/gcc/testsuite/gcc.target/mips/pr100760.c b/gcc/testsuite/gcc.target/mips/pr100760.c
new file mode 100644
index 0000000..d715b85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100760.c
@@ -0,0 +1,10 @@
+/* PR target/100760
+ This was triggering an ICE with "maximum number of generated reload
+ insns per insn achieved (90)" when compiled with -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef int32_t a __attribute__((__vector_size__(8)));
+void b() { a x = (a){1, 1}; }
diff --git a/gcc/testsuite/gcc.target/mips/pr100761.c b/gcc/testsuite/gcc.target/mips/pr100761.c
new file mode 100644
index 0000000..cc2598e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100761.c
@@ -0,0 +1,17 @@
+/* PR target/100761
+ This was triggering an ICE in mips_expand_vec_unpack when compiled with
+ -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef int8_t i8x8 __attribute__((__vector_size__(8)));
+typedef int16_t i16x8 __attribute__((__vector_size__(16)));
+
+i8x8 a;
+
+void f() {
+ i16x8 b = __builtin_convertvector (a, i16x8);
+}
diff --git a/gcc/testsuite/gcc.target/mips/pr100762.c b/gcc/testsuite/gcc.target/mips/pr100762.c
new file mode 100644
index 0000000..89c1185
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100762.c
@@ -0,0 +1,25 @@
+/* PR target/100762
+ This was triggering an ICE in mips_expand_vector_init when compiled with
+ -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef int32_t i32x2 __attribute__((__vector_size__(8)));
+
+i32x2 cmp(i32x2 a, i32x2 b) {
+ return a >= b;
+}
+
+i32x2 shift(i32x2 a, i32x2 b) {
+ return a >> b;
+}
+
+i32x2 mul(i32x2 a, i32x2 b) {
+ return a * b;
+}
+
+i32x2 div(i32x2 a, i32x2 b) {
+ return a / b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/div-vectorize-1.c b/gcc/testsuite/gcc.target/powerpc/div-vectorize-1.c
new file mode 100644
index 0000000..6208b2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/div-vectorize-1.c
@@ -0,0 +1,46 @@
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test vectorizer can exploit ISA 3.1 instructions Vector Divide
+ Signed/Unsigned Word/Doubleword for word/doubleword division. */
+
+#define N 128
+
+extern signed int si_a[N], si_b[N], si_c[N];
+extern unsigned int ui_a[N], ui_b[N], ui_c[N];
+extern signed long long sd_a[N], sd_b[N], sd_c[N];
+extern unsigned long long ud_a[N], ud_b[N], ud_c[N];
+
+__attribute__ ((noipa)) void
+test_si ()
+{
+ for (int i = 0; i < N; i++)
+ si_c[i] = si_a[i] / si_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ui ()
+{
+ for (int i = 0; i < N; i++)
+ ui_c[i] = ui_a[i] / ui_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_sd ()
+{
+ for (int i = 0; i < N; i++)
+ sd_c[i] = sd_a[i] / sd_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ud ()
+{
+ for (int i = 0; i < N; i++)
+ ud_c[i] = ud_a[i] / ud_b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvdivsw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvdivuw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvdivsd\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvdivud\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-cmove.c b/gcc/testsuite/gcc.target/powerpc/float128-cmove.c
new file mode 100644
index 0000000..2fae8dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-cmove.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#ifndef TYPE
+#ifdef __LONG_DOUBLE_IEEE128__
+#define TYPE long double
+
+#else
+#define TYPE _Float128
+#endif
+#endif
+
+/* Verify that the ISA 3.1 (power10) IEEE 128-bit conditional move instructions
+ are generated. */
+
+TYPE
+eq (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a == b) ? c : d;
+}
+
+TYPE
+ne (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a != b) ? c : d;
+}
+
+TYPE
+lt (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a < b) ? c : d;
+}
+
+TYPE
+le (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a <= b) ? c : d;
+}
+
+TYPE
+gt (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a > b) ? c : d;
+}
+
+TYPE
+ge (TYPE a, TYPE b, TYPE c, TYPE d)
+{
+ return (a >= b) ? c : d;
+}
+
+/* { dg-final { scan-assembler-times {\mxscmpeqqp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxscmpgeqp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxscmpgtqp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxxsel\M} 6 } } */
+/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c b/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c
new file mode 100644
index 0000000..6f7627c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c
@@ -0,0 +1,15 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+/* Test that the fminf128/fmaxf128 functions generate if/then/else and not a
+ call. */
+TYPE f128_min (TYPE a, TYPE b) { return (a < b) ? a : b; }
+TYPE f128_max (TYPE a, TYPE b) { return (b > a) ? b : a; }
+
+/* { dg-final { scan-assembler {\mxsmaxcqp\M} } } */
+/* { dg-final { scan-assembler {\mxsmincqp\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
index fe39751..ef8f729 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
@@ -1,6 +1,4 @@
-/* { dg-do compile { target lp64 } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-require-effective-target float128 } */
+/* { dg-require-effective-target ppc_float128_hw } */
/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
#ifndef TYPE
@@ -12,5 +10,8 @@
TYPE f128_min (TYPE a, TYPE b) { return __builtin_fminf128 (a, b); }
TYPE f128_max (TYPE a, TYPE b) { return __builtin_fmaxf128 (a, b); }
-/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */
-/* { dg-final { scan-assembler-not {\mbl\M} } } */
+/* Adjust code power10 which has native min/max instructions. */
+/* { dg-final { scan-assembler-times {\mxscmpuqp\M} 2 { target { ! has_arch_pwr10 } } } } */
+/* { dg-final { scan-assembler-times {\mxsmincqp\M} 1 { target has_arch_pwr10 } } } */
+/* { dg-final { scan-assembler-times {\mxsmaxcqp\M} 1 { target has_arch_pwr10 } } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-builtin-7.c b/gcc/testsuite/gcc.target/powerpc/mma-builtin-7.c
new file mode 100644
index 0000000..c661a4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mma-builtin-7.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+void
+foo (__vector_pair *dst, __vector_pair *src, long idx)
+{
+ dst[0] = __builtin_vsx_lxvp (0, src);
+ dst[2] = __builtin_vsx_lxvp (32, src);
+ dst[4] = __builtin_vsx_lxvp (64, src);
+ /* Non-constant offset should generate a lxvpx. */
+ dst[6] = __builtin_vsx_lxvp (idx, src);
+ /* Non-aligned offset should generate a plxvp. */
+ dst[8] = __builtin_vsx_lxvp (257, src);
+}
+
+#if !__has_builtin (__builtin_vsx_lxvp)
+# error "__has_builtin (__builtin_vsx_lxvp) failed"
+#endif
+
+/* { dg-final { scan-assembler-not {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mstxv\M} } } */
+/* { dg-final { scan-assembler-times {\mlxvp\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mlxvpx\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mplxvp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mstxvp\M} 5 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-builtin-8.c b/gcc/testsuite/gcc.target/powerpc/mma-builtin-8.c
new file mode 100644
index 0000000..af29e47
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mma-builtin-8.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+void
+foo (__vector_pair *dst, __vector_pair *src, long idx)
+{
+ __vector_pair pair = *src;
+ __builtin_vsx_stxvp (pair, 0, dst);
+ __builtin_vsx_stxvp (pair, 32, dst);
+ __builtin_vsx_stxvp (pair, 64, dst);
+ /* Non-constant offset should generate a stxvpx. */
+ __builtin_vsx_stxvp (pair, idx, dst);
+ /* Non-aligned offset should generate a pstxvp. */
+ __builtin_vsx_stxvp (pair, 257, dst);
+}
+
+#if !__has_builtin (__builtin_vsx_stxvp)
+# error "__has_builtin (__builtin_vsx_stxvp) failed"
+#endif
+
+/* { dg-final { scan-assembler-not {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mstxv\M} } } */
+/* { dg-final { scan-assembler-times {\mlxvp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mstxvp\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mstxvpx\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpstxvp\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mod-vectorize.c b/gcc/testsuite/gcc.target/powerpc/mod-vectorize.c
new file mode 100644
index 0000000..4d4f5cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mod-vectorize.c
@@ -0,0 +1,46 @@
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test vectorizer can exploit ISA 3.1 instructions Vector Modulo
+ Signed/Unsigned Word/Doubleword for word/doubleword modulo operations. */
+
+#define N 128
+
+extern signed int si_a[N], si_b[N], si_c[N];
+extern unsigned int ui_a[N], ui_b[N], ui_c[N];
+extern signed long long sd_a[N], sd_b[N], sd_c[N];
+extern unsigned long long ud_a[N], ud_b[N], ud_c[N];
+
+__attribute__ ((noipa)) void
+test_si ()
+{
+ for (int i = 0; i < N; i++)
+ si_c[i] = si_a[i] % si_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ui ()
+{
+ for (int i = 0; i < N; i++)
+ ui_c[i] = ui_a[i] % ui_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_sd ()
+{
+ for (int i = 0; i < N; i++)
+ sd_c[i] = sd_a[i] % sd_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ud ()
+{
+ for (int i = 0; i < N; i++)
+ ud_c[i] = ud_a[i] % ud_b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvmodsw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvmoduw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvmodsd\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvmodud\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mul-vectorize-1.c b/gcc/testsuite/gcc.target/powerpc/mul-vectorize-1.c
new file mode 100644
index 0000000..ba01d5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mul-vectorize-1.c
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test vectorizer can exploit ISA 2.07 instruction vmuluwm (Vector Multiply
+ Unsigned Word Modulo) for both signed and unsigned word multiplication. */
+
+#define N 128
+
+extern signed int si_a[N], si_b[N], si_c[N];
+extern unsigned int ui_a[N], ui_b[N], ui_c[N];
+
+__attribute__ ((noipa)) void
+test_si ()
+{
+ for (int i = 0; i < N; i++)
+ si_c[i] = si_a[i] * si_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ui ()
+{
+ for (int i = 0; i < N; i++)
+ ui_c[i] = ui_a[i] * ui_b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvmuluwm\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mul-vectorize-2.c b/gcc/testsuite/gcc.target/powerpc/mul-vectorize-2.c
new file mode 100644
index 0000000..12ca97a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mul-vectorize-2.c
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test vectorizer can exploit ISA 3.1 instruction vmulld (Vector Multiply
+ Low Doubleword) for both signed and unsigned doubleword multiplication. */
+
+#define N 128
+
+extern signed long long sd_a[N], sd_b[N], sd_c[N];
+extern unsigned long long ud_a[N], ud_b[N], ud_c[N];
+
+__attribute__ ((noipa)) void
+test_sd ()
+{
+ for (int i = 0; i < N; i++)
+ sd_c[i] = sd_a[i] * sd_b[i];
+}
+
+__attribute__ ((noipa)) void
+test_ud ()
+{
+ for (int i = 0; i < N; i++)
+ ud_c[i] = ud_a[i] * ud_b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvmulld\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
new file mode 100644
index 0000000..84685e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+unsigned __int128 u_div(unsigned __int128 a, unsigned __int128 b)
+{
+ return a/b;
+}
+
+unsigned __int128 u_mod(unsigned __int128 a, unsigned __int128 b)
+{
+ return a%b;
+}
+__int128 s_div(__int128 a, __int128 b)
+{
+ return a/b;
+}
+
+__int128 s_mod(__int128 a, __int128 b)
+{
+ return a%b;
+}
+
+/* { dg-final { scan-assembler {\mvdivsq\M} } } */
+/* { dg-final { scan-assembler {\mvdivuq\M} } } */
+/* { dg-final { scan-assembler {\mvmodsq\M} } } */
+/* { dg-final { scan-assembler {\mvmoduq\M} } } */
diff --git a/gcc/testsuite/gdc.dg/torture/pr101273.d b/gcc/testsuite/gdc.dg/torture/pr101273.d
new file mode 100644
index 0000000..e300e03
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr101273.d
@@ -0,0 +1,39 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101273
+// { dg-do run }
+
+struct S101273
+{
+ int x;
+ S101273* impl;
+ this(int x)
+ {
+ this.x = x;
+ this.impl = &this;
+ }
+ ~this() { }
+}
+
+S101273 makeS101273()
+{
+ return S101273(2);
+}
+
+S101273 nrvo101273()
+{
+ S101273 ret = makeS101273();
+ return ret;
+}
+
+S101273 rvo101273()
+{
+ return makeS101273();
+}
+
+void main()
+{
+ auto nrvo = nrvo101273();
+ assert(&nrvo is nrvo.impl);
+
+ auto rvo = rvo101273();
+ assert(&rvo is rvo.impl);
+}
diff --git a/gcc/testsuite/gdc.dg/torture/pr101282.d b/gcc/testsuite/gdc.dg/torture/pr101282.d
new file mode 100644
index 0000000..b75d5fc
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr101282.d
@@ -0,0 +1,23 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101282
+// { dg-do run }
+
+void main()
+{
+ struct S101282
+ {
+ int impl;
+ S101282 opUnary(string op : "-")()
+ {
+ return S101282(-impl);
+ }
+ int opCmp(int i)
+ {
+ return (impl < i) ? -1 : (impl > i) ? 1 : 0;
+ }
+ }
+ auto a = S101282(120);
+ a = -a;
+ assert(a.impl == -120);
+ a = a >= 0 ? a : -a;
+ assert(a.impl == 120);
+}
diff --git a/gcc/testsuite/gfortran.dg/implied_do_io_7.f90 b/gcc/testsuite/gfortran.dg/implied_do_io_7.f90
new file mode 100644
index 0000000..63927aa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/implied_do_io_7.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! PR 100227 - this was falsely optimized, leading to nonsense results.
+! Original test case by "Mathieu".
+
+program p
+ implicit none
+ integer, parameter :: nbmode = 3
+ integer :: k
+ real :: mass(nbmode*2)
+ character (len=80) :: line
+ do k = 1, nbmode*2
+ mass(k) = k
+ end do
+ write (unit=line,fmt='(*(F6.2))') (mass(k+k), k=1,nbmode)
+ if (line /= ' 2.00 4.00 6.00') stop 1
+end program
diff --git a/gcc/testsuite/gfortran.dg/pr101264.f90 b/gcc/testsuite/gfortran.dg/pr101264.f90
new file mode 100644
index 0000000..5602a70
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr101264.f90
@@ -0,0 +1,94 @@
+! { dg-do compile }
+! { dg-options "-Ofast" }
+ SUBROUTINE foo (a,b,c,d,trigs,inc1,inc2,inc3,inc4,lot,n,la)
+ IMPLICIT NONE (type, external)
+ INTEGER, PARAMETER :: wp = 8
+ INTEGER, PARAMETER :: iwp = 4
+ INTEGER(iwp) :: inc1
+ INTEGER(iwp) :: inc2
+ INTEGER(iwp) :: inc3
+ INTEGER(iwp) :: inc4
+ INTEGER(iwp) :: la
+ INTEGER(iwp) :: lot
+ INTEGER(iwp) :: n
+
+ REAL(wp) :: a(*)
+ REAL(wp) :: b(*)
+ REAL(wp) :: c(*)
+ REAL(wp) :: d(*)
+ REAL(wp) :: trigs(*)
+
+ REAL(wp) :: c1
+ REAL(wp) :: c2
+ REAL(wp) :: s1
+ REAL(wp) :: s2
+ REAL(wp) :: sin60
+
+ INTEGER(iwp) :: i
+ INTEGER(iwp) :: ia
+ INTEGER(iwp) :: ib
+ INTEGER(iwp) :: ibase
+ INTEGER(iwp) :: ic
+ INTEGER(iwp) :: iink
+ INTEGER(iwp) :: ijk
+ INTEGER(iwp) :: j
+ INTEGER(iwp) :: ja
+ INTEGER(iwp) :: jb
+ INTEGER(iwp) :: jbase
+ INTEGER(iwp) :: jc
+ INTEGER(iwp) :: jink
+ INTEGER(iwp) :: jump
+ INTEGER(iwp) :: k
+ INTEGER(iwp) :: kb
+ INTEGER(iwp) :: kc
+ INTEGER(iwp) :: kstop
+ INTEGER(iwp) :: l
+ INTEGER(iwp) :: m
+
+ sin60=0.866025403784437_wp
+
+ ia = 1
+ ib = ia + (2*m-la)*inc1
+ ic = ib
+ ja = 1
+ jb = ja + jink
+ jc = jb + jink
+
+ DO k = la, kstop, la
+ kb = k + k
+ kc = kb + kb
+ c1 = trigs(kb+1)
+ s1 = trigs(kb+2)
+ c2 = trigs(kc+1)
+ s2 = trigs(kc+2)
+ ibase = 0
+ DO l = 1, la
+ i = ibase
+ j = jbase
+ DO ijk = 1, lot
+ c(ja+j) = a(ia+i) + (a(ib+i)+a(ic+i))
+ d(ja+j) = b(ia+i) + (b(ib+i)-b(ic+i))
+ c(jb+j) = c1*((a(ia+i)-0.5_wp*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)+ &
+ & b(ic+i)))) &
+ & - s1*((b(ia+i)-0.5_wp*(b(ib+i)-b(ic+i)))+(sin60*(a(ib+i)- &
+ & a(ic+i))))
+ d(jb+j) = s1*((a(ia+i)-0.5_wp*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)+ &
+ & b(ic+i)))) &
+ & + c1*((b(ia+i)-0.5_wp*(b(ib+i)-b(ic+i)))+(sin60*(a(ib+i)- &
+ & a(ic+i))))
+ c(jc+j) = c2*((a(ia+i)-0.5_wp*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)+ &
+ & b(ic+i)))) &
+ & - s2*((b(ia+i)-0.5_wp*(b(ib+i)-b(ic+i)))-(sin60*(a(ib+i)- &
+ & a(ic+i))))
+ i = i + inc3
+ j = j + inc4
+ END DO
+ ibase = ibase + inc1
+ jbase = jbase + inc2
+ END DO
+ ia = ia + iink
+ ib = ib + iink
+ ic = ic - iink
+ jbase = jbase + jump
+ END DO
+ END
diff --git a/gcc/testsuite/gfortran.dg/pr101267.f90 b/gcc/testsuite/gfortran.dg/pr101267.f90
new file mode 100644
index 0000000..12723cf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr101267.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+! { dg-options "-Ofast" }
+! { dg-additional-options "-march=znver2" { target x86_64-*-* i?86-*-* } }
+ SUBROUTINE sfddagd( regime, znt,ite ,jte )
+ REAL, DIMENSION( ime, IN) :: regime, znt
+ REAL, DIMENSION( ite, jte) :: wndcor_u
+ LOGICAL wrf_dm_on_monitor
+ IF( int4 == 1 ) THEN
+ DO j=jts,jtf
+ DO i=itsu,itf
+ reg = regime(i, j)
+ IF( reg > 10.0 ) THEN
+ znt0 = znt(i-1, j) + znt(i, j)
+ IF( znt0 <= 0.2) THEN
+ wndcor_u(i,j) = 0.2
+ ENDIF
+ ENDIF
+ ENDDO
+ ENDDO
+ IF ( wrf_dm_on_monitor()) THEN
+ ENDIF
+ ENDIF
+ END
diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp
index e9119f0..d17308d 100644
--- a/gcc/testsuite/lib/gcc-defs.exp
+++ b/gcc/testsuite/lib/gcc-defs.exp
@@ -176,6 +176,40 @@ if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
global gcc_runtest_parallelize_dir
global gcc_runtest_parallelize_last
+ # GCC testsuite is parallelised by starting N runtest processes -- each
+ # with its own test directory. These N runtest processes ALL go through
+ # the relevant .exp and ALL attempt to run every test. And they go
+ # through the tests the same order -- this is important, and if there is
+ # a bug that causes different runtest processes to enumerate the tests
+ # differently, then things will break and some tests will be skipped, while
+ # others will be ran several times.
+ # So, just before a runtest processes runs a specific test it asks
+ # "runtest_file_p" routine whether a particular test is part of
+ # the requested testsuite. We override this function so that it
+ # returns "yes" to the first-arrived runtest process, and "no" to all
+ # subsequent runtest processes -- this is implemented by creating a marker
+ # file, which persist till the end of the test run. We optimize this
+ # a bit by batching 10 tests and using a single marker file for the batch.
+ #
+ # Note that the runtest processes all race each other to get to the next
+ # test batch. This means that batch allocation between testsuite runs
+ # is very likely to change.
+ #
+ # To confirm or deny suspicion that tests are skipped or executed
+ # multiple times due to runtest processes enumerating tests differently ...
+ # 1. Uncomment the three below "verbose -log gcc_parallel_test_run_p ..."
+ # debug print-outs.
+ # 2. Run the testsuite with "-v" added to RUNTESTFLAGS
+ # 3. Extract debug print-outs with something like:
+ # for i in $(find -name "*.log.sep"); do
+ # grep gcc_parallel_test_run_p $i \
+ # | sed -e "s/\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\)/\3 \2/" \
+ # | sed -e "s#\(/testsuite/[a-z+]*\)[0-9]*/#\1N/#" > $i.order
+ # done
+ # 4. Compare debug print-outs produced by individual runtest processes:
+ # find -name "*.log.sep.order" | xargs md5sum | sort
+ # 5. Check that MD5 hashes of all .order files of the same testsuite match
+ # and investigate if they don't.
set gcc_runtest_parallelize_counter 0
set gcc_runtest_parallelize_counter_minor 0
set gcc_runtest_parallelize_enable 1
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 51d8a11..81f4bb2 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -641,6 +641,7 @@ proc gcc-dg-frontend-supports-ctf { target_compile trivial } {
proc gcc-dg-target-supports-debug-format { target_compile trivial type } {
global srcdir subdir
+ if {$type == "-gctf" && [istarget *-*-aix*]} { return 0 }
set comp_output [$target_compile \
"$srcdir/$subdir/$trivial" "trivial.S" assembly \
"additional_flags=$type"]
@@ -656,29 +657,29 @@ proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } {
if ![info exists DEBUG_TORTURE_OPTIONS] {
set DEBUG_TORTURE_OPTIONS ""
foreach type {-gctf -gdwarf-2 -gstabs -gstabs+ -gxcoff -gxcoff+} {
- if { $type == "-gctf" } {
- if [expr [gcc-dg-frontend-supports-ctf \
- $target_compile $trivial]] {
- # At this time, running tests with various opt levels or
- # ctf debug info levels does not add value.
- lappend DEBUG_TORTURE_OPTIONS [list "${type}"]
+ if [expr [gcc-dg-target-supports-debug-format \
+ $target_compile $trivial $type]] {
+ if { $type == "-gctf" } {
+ if [expr [gcc-dg-frontend-supports-ctf \
+ $target_compile $trivial]] {
+ # At this time, running tests with various opt levels or
+ # ctf debug info levels does not add value.
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}"]
+ }
+ continue
}
- } else {
- if [expr [gcc-dg-target-supports-debug-format \
- $target_compile $trivial $type]] {
- foreach level {1 "" 3} {
- if { ($type == "-gdwarf-2") && ($level != "") } {
- lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"]
- foreach opt $opt_opts {
- lappend DEBUG_TORTURE_OPTIONS \
- [list "${type}" "-g${level}" "$opt" ]
- }
- } else {
- lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
- foreach opt $opt_opts {
- lappend DEBUG_TORTURE_OPTIONS \
- [list "${type}${level}" "$opt" ]
- }
+ foreach level {1 "" 3} {
+ if { ($type == "-gdwarf-2") && ($level != "") } {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}" "-g${level}" "$opt" ]
+ }
+ } else {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}${level}" "$opt" ]
}
}
}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 7f78c55..789723f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6127,6 +6127,16 @@ proc check_effective_target_has_arch_pwr9 { } {
}]
}
+proc check_effective_target_has_arch_pwr10 { } {
+ return [check_no_compiler_messages arch_pwr10 assembly {
+ #ifndef _ARCH_PWR10
+ #error does not have power10 support.
+ #else
+ /* "has power10 support" */
+ #endif
+ }]
+}
+
# Return 1 if this is a PowerPC target supporting -mcpu=power10.
# Limit this to 64-bit linux systems for now until other targets support
# power10.
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index e74bd1f..c270d03 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4413,12 +4413,8 @@ ipa_tm_scan_irr_block (basic_block bb)
is to wrap it in a __tm_waiver block. This is not
yet implemented, so we can't check for it. */
if (is_tm_safe (current_function_decl))
- {
- tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
- SET_EXPR_LOCATION (t, gimple_location (stmt));
- error ("%K%<asm%> not allowed in %<transaction_safe%> function",
- t);
- }
+ error_at (gimple_location (stmt),
+ "%<asm%> not allowed in %<transaction_safe%> function");
return true;
default:
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 95b8ef3..8bb214b 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -276,15 +276,6 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
t = va_arg (*text->args_ptr, tree);
break;
- case 'G':
- percent_G_format (text);
- return true;
-
- case 'K':
- t = va_arg (*text->args_ptr, tree);
- percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t));
- return true;
-
default:
return false;
}
@@ -305,6 +296,73 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
return true;
}
+/* Set the locations of call sites along the inlining stack corresponding
+ to the DIAGNOSTIC location. */
+
+static void
+set_inlining_locations (diagnostic_context *,
+ diagnostic_info *diagnostic)
+{
+ location_t loc = diagnostic_location (diagnostic);
+ tree block = LOCATION_BLOCK (loc);
+
+ /* Count the number of locations in system headers. When all are,
+ warnings are suppressed by -Wno-system-headers. Otherwise, they
+ involve some user code, possibly inlined into a function in a system
+ header, and are not treated as coming from system headers. */
+ unsigned nsyslocs = 0;
+
+ /* Use a reference to the vector of locations for convenience. */
+ auto &ilocs = diagnostic->m_iinfo.m_ilocs;
+
+ while (block && TREE_CODE (block) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (block))
+ {
+ tree ao = BLOCK_ABSTRACT_ORIGIN (block);
+ if (TREE_CODE (ao) == FUNCTION_DECL)
+ {
+ if (!diagnostic->m_iinfo.m_ao)
+ diagnostic->m_iinfo.m_ao = block;
+
+ location_t bsloc = BLOCK_SOURCE_LOCATION (block);
+ ilocs.safe_push (bsloc);
+ if (in_system_header_at (bsloc))
+ ++nsyslocs;
+ }
+ else if (TREE_CODE (ao) != BLOCK)
+ break;
+
+ block = BLOCK_SUPERCONTEXT (block);
+ }
+
+ if (ilocs.length ())
+ {
+ /* When there is an inlining context use the macro expansion
+ location for the original location and bump up NSYSLOCS if
+ it's in a system header since it's not counted above. */
+ location_t sysloc = expansion_point_location_if_in_system_header (loc);
+ if (sysloc != loc)
+ {
+ loc = sysloc;
+ ++nsyslocs;
+ }
+ }
+ else
+ {
+ /* When there's no inlining context use the original location
+ and set NSYSLOCS accordingly. */
+ nsyslocs = in_system_header_at (loc) != 0;
+ }
+
+ ilocs.safe_push (loc);
+
+ /* Set if all locations are in a system header. */
+ diagnostic->m_iinfo.m_allsyslocs = nsyslocs == ilocs.length ();
+
+ if (tree *ao = pp_ti_abstract_origin (&diagnostic->message))
+ *ao = (tree)diagnostic->m_iinfo.m_ao;
+}
+
/* Sets CONTEXT to use language independent diagnostics. */
void
tree_diagnostics_defaults (diagnostic_context *context)
@@ -314,4 +372,5 @@ tree_diagnostics_defaults (diagnostic_context *context)
diagnostic_format_decoder (context) = default_tree_printer;
context->print_path = default_tree_diagnostic_path_printer;
context->make_json_for_path = default_tree_make_json_for_path;
+ context->set_locations_cb = set_inlining_locations;
}
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index bcbe669..fde07df 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -4433,32 +4433,6 @@ newline_and_indent (pretty_printer *pp, int spc)
INDENT (spc);
}
-/* Handle the %K format for TEXT. Separate from default_tree_printer
- so it can also be used in front ends.
- The location LOC and BLOCK are expected to be extracted by the caller
- from the %K argument arg via EXPR_LOCATION(arg) and TREE_BLOCK(arg). */
-
-void
-percent_K_format (text_info *text, location_t loc, tree block)
-{
- text->set_location (0, loc, SHOW_RANGE_WITH_CARET);
- gcc_assert (pp_ti_abstract_origin (text) != NULL);
- *pp_ti_abstract_origin (text) = NULL;
-
- while (block
- && TREE_CODE (block) == BLOCK
- && BLOCK_ABSTRACT_ORIGIN (block))
- {
- tree ao = BLOCK_ABSTRACT_ORIGIN (block);
- if (TREE_CODE (ao) == FUNCTION_DECL)
- {
- *pp_ti_abstract_origin (text) = block;
- break;
- }
- block = BLOCK_SUPERCONTEXT (block);
- }
-}
-
/* Print the identifier ID to PRETTY-PRINTER. */
void
diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h
index cafe9aa..dacd256 100644
--- a/gcc/tree-pretty-print.h
+++ b/gcc/tree-pretty-print.h
@@ -52,7 +52,6 @@ extern int op_prio (const_tree);
extern const char *op_symbol_code (enum tree_code);
extern void pretty_print_string (pretty_printer *, const char *, size_t);
extern void print_call_name (pretty_printer *, tree, dump_flags_t);
-extern void percent_K_format (text_info *, location_t, tree);
extern void pp_tree_identifier (pretty_printer *, tree);
extern void dump_function_header (FILE *, tree, dump_flags_t);
extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 4258541..9ce6214 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -3563,7 +3563,7 @@ pass_post_ipa_warn::execute (function *fun)
if (argno == 0)
{
if (warning_at (loc, OPT_Wnonnull,
- "%G%qs pointer is null", stmt, "this")
+ "%qs pointer is null", "this")
&& fndecl)
inform (DECL_SOURCE_LOCATION (fndecl),
"in a call to non-static member function %qD",
@@ -3572,8 +3572,8 @@ pass_post_ipa_warn::execute (function *fun)
}
if (!warning_at (loc, OPT_Wnonnull,
- "%Gargument %u null where non-null "
- "expected", stmt, argno))
+ "argument %u null where non-null "
+ "expected", argno))
continue;
tree fndecl = gimple_call_fndecl (stmt);
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index c3939a6..98daa8a 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -813,15 +813,11 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
break;
}
- /* We have visited ourselves already so ignore STMT for the
- purpose of chaining. */
- if (use_stmt == stmt)
- ;
/* In simple cases we can look through PHI nodes, but we
have to be careful with loops and with memory references
containing operands that are also operands of PHI nodes.
See gcc.c-torture/execute/20051110-*.c. */
- else if (gimple_code (use_stmt) == GIMPLE_PHI)
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
{
/* If we already visited this PHI ignore it for further
processing. */
@@ -861,6 +857,10 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
fail = true;
break;
}
+ /* We have visited ourselves already so ignore STMT for the
+ purpose of chaining. */
+ else if (use_stmt == stmt)
+ ;
/* If this is a store, remember it as we possibly need to walk the
defs uses. */
else if (gimple_vdef (use_stmt))
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 48c952a..81b4ec2 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -122,7 +122,9 @@ public:
hashval_t hash; /* Its hash value. */
/* The memory access itself and associated caching of alias-oracle
- query meta-data. */
+ query meta-data. We are using mem.ref == error_mark_node for the
+ case the reference is represented by its single access stmt
+ in accesses_in_loop[0]. */
ao_ref mem;
bitmap stored; /* The set of loops in that this memory location
@@ -130,8 +132,7 @@ public:
bitmap loaded; /* The set of loops in that this memory location
is loaded from. */
vec<mem_ref_loc> accesses_in_loop;
- /* The locations of the accesses. Vector
- indexed by the loop number. */
+ /* The locations of the accesses. */
/* The following set is computed on demand. */
bitmap_head dep_loop; /* The set of loops in that the memory
@@ -194,8 +195,14 @@ mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2)
{
if (obj2->max_size_known_p ())
return (mem1->ref_decomposed
- && operand_equal_p (mem1->mem.base, obj2->base, 0)
- && known_eq (mem1->mem.offset, obj2->offset)
+ && ((TREE_CODE (mem1->mem.base) == MEM_REF
+ && TREE_CODE (obj2->base) == MEM_REF
+ && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0),
+ TREE_OPERAND (obj2->base, 0), 0)
+ && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT + mem1->mem.offset,
+ mem_ref_offset (obj2->base) * BITS_PER_UNIT + obj2->offset))
+ || (operand_equal_p (mem1->mem.base, obj2->base, 0)
+ && known_eq (mem1->mem.offset, obj2->offset)))
&& known_eq (mem1->mem.size, obj2->size)
&& known_eq (mem1->mem.max_size, obj2->max_size)
&& mem1->mem.volatile_p == obj2->volatile_p
@@ -1459,7 +1466,22 @@ gather_mem_refs_stmt (class loop *loop, gimple *stmt)
return;
mem = simple_mem_ref_in_stmt (stmt, &is_stored);
- if (!mem)
+ if (!mem && is_gimple_assign (stmt))
+ {
+ /* For aggregate copies record distinct references but use them
+ only for disambiguation purposes. */
+ id = memory_accesses.refs_list.length ();
+ ref = mem_ref_alloc (NULL, 0, id);
+ memory_accesses.refs_list.safe_push (ref);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Unhandled memory reference %u: ", id);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ }
+ record_mem_ref_loc (ref, stmt, mem);
+ is_stored = gimple_vdef (stmt);
+ }
+ else if (!mem)
{
/* We use the shared mem_ref for all unanalyzable refs. */
id = UNANALYZABLE_MEM_ID;
@@ -1500,8 +1522,21 @@ gather_mem_refs_stmt (class loop *loop, gimple *stmt)
&& (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off)))
{
ref_decomposed = true;
- hash = iterative_hash_expr (ao_ref_base (&aor), 0);
- hash = iterative_hash_host_wide_int (offset, hash);
+ tree base = ao_ref_base (&aor);
+ poly_int64 moffset;
+ HOST_WIDE_INT mcoffset;
+ if (TREE_CODE (base) == MEM_REF
+ && (mem_ref_offset (base) * BITS_PER_UNIT + offset).to_shwi (&moffset)
+ && moffset.is_constant (&mcoffset))
+ {
+ hash = iterative_hash_expr (TREE_OPERAND (base, 0), 0);
+ hash = iterative_hash_host_wide_int (mcoffset, hash);
+ }
+ else
+ {
+ hash = iterative_hash_expr (base, 0);
+ hash = iterative_hash_host_wide_int (offset, hash);
+ }
hash = iterative_hash_host_wide_int (size, hash);
}
else
@@ -1576,7 +1611,8 @@ gather_mem_refs_stmt (class loop *loop, gimple *stmt)
mark_ref_stored (ref, loop);
}
/* A not simple memory op is also a read when it is a write. */
- if (!is_stored || id == UNANALYZABLE_MEM_ID)
+ if (!is_stored || id == UNANALYZABLE_MEM_ID
+ || ref->mem.ref == error_mark_node)
{
bitmap_set_bit (&memory_accesses.refs_loaded_in_loop[loop->num], ref->id);
mark_ref_loaded (ref, loop);
@@ -1695,6 +1731,9 @@ mem_refs_may_alias_p (im_mem_ref *mem1, im_mem_ref *mem2,
hash_map<tree, name_expansion *> **ttae_cache,
bool tbaa_p)
{
+ gcc_checking_assert (mem1->mem.ref != error_mark_node
+ && mem2->mem.ref != error_mark_node);
+
/* Perform BASE + OFFSET analysis -- if MEM1 and MEM2 are based on the same
object and their offset differ in such a way that the locations cannot
overlap, then they cannot alias. */
@@ -2471,6 +2510,13 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
gcc_assert (data);
if (data->ref == UNANALYZABLE_MEM_ID)
return -1;
+ /* Stop at memory references which we can't move. */
+ else if (memory_accesses.refs_list[data->ref]->mem.ref == error_mark_node)
+ {
+ /* Mark refs_not_in_seq as unsupported. */
+ bitmap_ior_into (refs_not_supported, refs_not_in_seq);
+ return 1;
+ }
/* One of the stores we want to apply SM to and we've not yet seen. */
else if (bitmap_clear_bit (refs_not_in_seq, data->ref))
{
@@ -2779,7 +2825,8 @@ ref_indep_loop_p (class loop *loop, im_mem_ref *ref, dep_kind kind)
else
refs_to_check = &memory_accesses.refs_stored_in_loop[loop->num];
- if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
+ if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID)
+ || ref->mem.ref == error_mark_node)
indep_p = false;
else
{
@@ -2806,7 +2853,20 @@ ref_indep_loop_p (class loop *loop, im_mem_ref *ref, dep_kind kind)
EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
{
im_mem_ref *aref = memory_accesses.refs_list[i];
- if (!refs_independent_p (ref, aref, kind != sm_waw))
+ if (aref->mem.ref == error_mark_node)
+ {
+ gimple *stmt = aref->accesses_in_loop[0].stmt;
+ if ((kind == sm_war
+ && ref_maybe_used_by_stmt_p (stmt, &ref->mem,
+ kind != sm_waw))
+ || stmt_may_clobber_ref_p_1 (stmt, &ref->mem,
+ kind != sm_waw))
+ {
+ indep_p = false;
+ break;
+ }
+ }
+ else if (!refs_independent_p (ref, aref, kind != sm_waw))
{
indep_p = false;
break;
@@ -2839,6 +2899,10 @@ can_sm_ref_p (class loop *loop, im_mem_ref *ref)
if (!MEM_ANALYZABLE (ref))
return false;
+ /* Can't hoist/sink aggregate copies. */
+ if (ref->mem.ref == error_mark_node)
+ return false;
+
/* It should be movable. */
if (!is_gimple_reg_type (TREE_TYPE (ref->mem.ref))
|| TREE_THIS_VOLATILE (ref->mem.ref)
@@ -3239,7 +3303,7 @@ pass_lim::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
- unsigned int todo = loop_invariant_motion_in_fun (fun, true);
+ unsigned int todo = loop_invariant_motion_in_fun (fun, flag_move_loop_stores);
if (!in_loop_pipeline)
loop_optimizer_finalize ();
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index ab12e85..7a98b7a 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -50,20 +50,20 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-fold.h"
#include "internal-fn.h"
#include "gimple-range.h"
+#include "gimple-match.h"
+#include "dbgcnt.h"
static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
tree, tree);
static bool match_simplify_replacement (basic_block, basic_block,
- edge, edge, gphi *, tree, tree);
+ edge, edge, gphi *, tree, tree, bool);
static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree,
gimple *);
static int value_replacement (basic_block, basic_block,
edge, edge, gphi *, tree, tree);
static bool minmax_replacement (basic_block, basic_block,
edge, edge, gphi *, tree, tree);
-static bool abs_replacement (basic_block, basic_block,
- edge, edge, gphi *, tree, tree);
static bool spaceship_replacement (basic_block, basic_block,
edge, edge, gphi *, tree, tree);
static bool cond_removal_in_popcount_clz_ctz_pattern (basic_block, basic_block,
@@ -345,11 +345,9 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
/* Do the replacement of conditional if it can be done. */
if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
cfgchanged = true;
- else if (!early_p
- && match_simplify_replacement (bb, bb1, e1, e2, phi,
- arg0, arg1))
- cfgchanged = true;
- else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
+ else if (match_simplify_replacement (bb, bb1, e1, e2, phi,
+ arg0, arg1,
+ early_p))
cfgchanged = true;
else if (!early_p
&& cond_removal_in_popcount_clz_ctz_pattern (bb, bb1, e1,
@@ -393,7 +391,7 @@ replace_phi_edge_with_variable (basic_block cond_block,
gimple_stmt_iterator gsi;
tree phi_result = PHI_RESULT (phi);
- /* Duplicate range info if we're the only things setting the target PHI.
+ /* Duplicate range info if they are the only things setting the target PHI.
This is needed as later on, the new_tree will be replacing
The assignement of the PHI.
For an example:
@@ -401,19 +399,22 @@ replace_phi_edge_with_variable (basic_block cond_block,
_4 = min<a_1, 255>
goto bb2
- range<-INF,255>
+ # RANGE [-INF, 255]
a_3 = PHI<_4(1)>
bb3:
use(a_3)
- And _4 gets prograted into the use of a_3 and losing the range info.
- This can't be done for more than 2 incoming edges as the progration
- won't happen. */
+ And _4 gets propagated into the use of a_3 and losing the range info.
+ This can't be done for more than 2 incoming edges as the propagation
+ won't happen.
+ The new_tree needs to be defined in the same basic block as the conditional. */
if (TREE_CODE (new_tree) == SSA_NAME
&& EDGE_COUNT (gimple_bb (phi)->preds) == 2
&& INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
&& !SSA_NAME_RANGE_INFO (new_tree)
- && SSA_NAME_RANGE_INFO (phi_result))
+ && SSA_NAME_RANGE_INFO (phi_result)
+ && gimple_bb (SSA_NAME_DEF_STMT (new_tree)) == cond_block
+ && dbg_cnt (phiopt_edge_range))
duplicate_ssa_name_range_info (new_tree,
SSA_NAME_RANGE_TYPE (phi_result),
SSA_NAME_RANGE_INFO (phi_result));
@@ -811,6 +812,128 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
return true;
}
+/* Return TRUE if SEQ/OP pair should be allowed during early phiopt.
+ Currently this is to allow MIN/MAX and ABS/NEGATE and constants. */
+static bool
+phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
+{
+ /* Don't allow functions. */
+ if (!op.code.is_tree_code ())
+ return false;
+ tree_code code = (tree_code)op.code;
+
+ /* For non-empty sequence, only allow one statement. */
+ if (!gimple_seq_empty_p (seq))
+ {
+ /* Check to make sure op was already a SSA_NAME. */
+ if (code != SSA_NAME)
+ return false;
+ if (!gimple_seq_singleton_p (seq))
+ return false;
+ gimple *stmt = gimple_seq_first_stmt (seq);
+ /* Only allow assignments. */
+ if (!is_gimple_assign (stmt))
+ return false;
+ if (gimple_assign_lhs (stmt) != op.ops[0])
+ return false;
+ code = gimple_assign_rhs_code (stmt);
+ }
+
+ switch (code)
+ {
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case ABS_EXPR:
+ case ABSU_EXPR:
+ case NEGATE_EXPR:
+ case SSA_NAME:
+ return true;
+ case INTEGER_CST:
+ case REAL_CST:
+ case VECTOR_CST:
+ case FIXED_CST:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
+ Return NULL if nothing can be simplified or the resulting simplified value
+ with parts pushed if EARLY_P was true. Also rejects non allowed tree code
+ if EARLY_P is set.
+ Takes the comparison from COMP_STMT and two args, ARG0 and ARG1 and tries
+ to simplify CMP ? ARG0 : ARG1.
+ Also try to simplify (!CMP) ? ARG1 : ARG0 if the non-inverse failed. */
+static tree
+gimple_simplify_phiopt (bool early_p, tree type, gimple *comp_stmt,
+ tree arg0, tree arg1,
+ gimple_seq *seq)
+{
+ tree result;
+ gimple_seq seq1 = NULL;
+ enum tree_code comp_code = gimple_cond_code (comp_stmt);
+ location_t loc = gimple_location (comp_stmt);
+ tree cmp0 = gimple_cond_lhs (comp_stmt);
+ tree cmp1 = gimple_cond_rhs (comp_stmt);
+ /* To handle special cases like floating point comparison, it is easier and
+ less error-prone to build a tree and gimplify it on the fly though it is
+ less efficient.
+ Don't use fold_build2 here as that might create (bool)a instead of just
+ "a != 0". */
+ tree cond = build2_loc (loc, comp_code, boolean_type_node,
+ cmp0, cmp1);
+ gimple_match_op op (gimple_match_cond::UNCOND,
+ COND_EXPR, type, cond, arg0, arg1);
+
+ if (op.resimplify (&seq1, follow_all_ssa_edges))
+ {
+ /* Early we want only to allow some generated tree codes. */
+ if (!early_p
+ || phiopt_early_allow (seq1, op))
+ {
+ result = maybe_push_res_to_seq (&op, &seq1);
+ if (result)
+ {
+ gimple_seq_add_seq_without_update (seq, seq1);
+ return result;
+ }
+ }
+ }
+ gimple_seq_discard (seq1);
+ seq1 = NULL;
+
+ /* Try the inverted comparison, that is !COMP ? ARG1 : ARG0. */
+ comp_code = invert_tree_comparison (comp_code, HONOR_NANS (cmp0));
+
+ if (comp_code == ERROR_MARK)
+ return NULL;
+
+ cond = build2_loc (loc,
+ comp_code, boolean_type_node,
+ cmp0, cmp1);
+ gimple_match_op op1 (gimple_match_cond::UNCOND,
+ COND_EXPR, type, cond, arg1, arg0);
+
+ if (op1.resimplify (&seq1, follow_all_ssa_edges))
+ {
+ /* Early we want only to allow some generated tree codes. */
+ if (!early_p
+ || phiopt_early_allow (seq1, op1))
+ {
+ result = maybe_push_res_to_seq (&op1, &seq1);
+ if (result)
+ {
+ gimple_seq_add_seq_without_update (seq, seq1);
+ return result;
+ }
+ }
+ }
+ gimple_seq_discard (seq1);
+
+ return NULL;
+}
+
/* The function match_simplify_replacement does the main work of doing the
replacement using match and simplify. Return true if the replacement is done.
Otherwise return false.
@@ -820,10 +943,9 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
static bool
match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
edge e0, edge e1, gphi *phi,
- tree arg0, tree arg1)
+ tree arg0, tree arg1, bool early_p)
{
gimple *stmt;
- tree cond;
gimple_stmt_iterator gsi;
edge true_edge, false_edge;
gimple_seq seq = NULL;
@@ -884,15 +1006,6 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
stmt = last_stmt (cond_bb);
- /* To handle special cases like floating point comparison, it is easier and
- less error-prone to build a tree and gimplify it on the fly though it is
- less efficient.
- Don't use fold_build2 here as that might create (bool)a instead of just
- "a != 0". */
- cond = build2_loc (gimple_location (stmt),
- gimple_cond_code (stmt), boolean_type_node,
- gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
-
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
@@ -900,10 +1013,9 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
std::swap (arg0, arg1);
tree type = TREE_TYPE (gimple_phi_result (phi));
- result = gimple_simplify (COND_EXPR, type,
- cond,
- arg0, arg1,
- &seq, NULL);
+ result = gimple_simplify_phiopt (early_p, type, stmt,
+ arg0, arg1,
+ &seq);
if (!result)
return false;
@@ -2530,134 +2642,6 @@ cond_removal_in_popcount_clz_ctz_pattern (basic_block cond_bb,
return true;
}
-/* The function absolute_replacement does the main work of doing the absolute
- replacement. Return true if the replacement is done. Otherwise return
- false.
- bb is the basic block where the replacement is going to be done on. arg0
- is argument 0 from the phi. Likewise for arg1. */
-
-static bool
-abs_replacement (basic_block cond_bb, basic_block middle_bb,
- edge e0 ATTRIBUTE_UNUSED, edge e1,
- gphi *phi, tree arg0, tree arg1)
-{
- tree result;
- gassign *new_stmt;
- gimple *cond;
- gimple_stmt_iterator gsi;
- edge true_edge, false_edge;
- gimple *assign;
- edge e;
- tree rhs, lhs;
- bool negate;
- enum tree_code cond_code;
-
- /* If the type says honor signed zeros we cannot do this
- optimization. */
- if (HONOR_SIGNED_ZEROS (arg1))
- return false;
-
- /* OTHER_BLOCK must have only one executable statement which must have the
- form arg0 = -arg1 or arg1 = -arg0. */
-
- assign = last_and_only_stmt (middle_bb);
- /* If we did not find the proper negation assignment, then we cannot
- optimize. */
- if (assign == NULL)
- return false;
-
- /* If we got here, then we have found the only executable statement
- in OTHER_BLOCK. If it is anything other than arg = -arg1 or
- arg1 = -arg0, then we cannot optimize. */
- if (gimple_code (assign) != GIMPLE_ASSIGN)
- return false;
-
- lhs = gimple_assign_lhs (assign);
-
- if (gimple_assign_rhs_code (assign) != NEGATE_EXPR)
- return false;
-
- rhs = gimple_assign_rhs1 (assign);
-
- /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
- if (!(lhs == arg0 && rhs == arg1)
- && !(lhs == arg1 && rhs == arg0))
- return false;
-
- cond = last_stmt (cond_bb);
- result = PHI_RESULT (phi);
-
- /* Only relationals comparing arg[01] against zero are interesting. */
- cond_code = gimple_cond_code (cond);
- if (cond_code != GT_EXPR && cond_code != GE_EXPR
- && cond_code != LT_EXPR && cond_code != LE_EXPR)
- return false;
-
- /* Make sure the conditional is arg[01] OP y. */
- if (gimple_cond_lhs (cond) != rhs)
- return false;
-
- if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond)))
- ? real_zerop (gimple_cond_rhs (cond))
- : integer_zerop (gimple_cond_rhs (cond)))
- ;
- else
- return false;
-
- /* We need to know which is the true edge and which is the false
- edge so that we know if have abs or negative abs. */
- extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
-
- /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
- will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
- the false edge goes to OTHER_BLOCK. */
- if (cond_code == GT_EXPR || cond_code == GE_EXPR)
- e = true_edge;
- else
- e = false_edge;
-
- if (e->dest == middle_bb)
- negate = true;
- else
- negate = false;
-
- /* If the code negates only iff positive then make sure to not
- introduce undefined behavior when negating or computing the absolute.
- ??? We could use range info if present to check for arg1 == INT_MIN. */
- if (negate
- && (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg1))
- && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
- return false;
-
- result = duplicate_ssa_name (result, NULL);
-
- if (negate)
- lhs = make_ssa_name (TREE_TYPE (result));
- else
- lhs = result;
-
- /* Build the modify expression with abs expression. */
- new_stmt = gimple_build_assign (lhs, ABS_EXPR, rhs);
-
- gsi = gsi_last_bb (cond_bb);
- gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
-
- if (negate)
- {
- /* Get the right GSI. We want to insert after the recently
- added ABS_EXPR statement (which we know is the first statement
- in the block. */
- new_stmt = gimple_build_assign (result, NEGATE_EXPR, lhs);
-
- gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
- }
-
- replace_phi_edge_with_variable (cond_bb, e1, phi, result);
-
- /* Note that we optimized this PHI. */
- return true;
-}
-
/* Auxiliary functions to determine the set of memory accesses which
can't trap because they are preceded by accesses to the same memory
portion. We do that for MEM_REFs, so we only need to track
@@ -3594,7 +3578,7 @@ gate_hoist_loads (void)
ABS Replacement
---------------
- This transformation, implemented in abs_replacement, replaces
+ This transformation, implemented in match_simplify_replacement, replaces
bb0:
if (a >= 0) goto bb2; else goto bb1;
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 13ea107..94257df 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2022,13 +2022,12 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry,
warned = (writefn
? warning_at (loc, OPT_Wstringop_overflow_,
- "%G%qD writing one too many bytes into a region "
+ "%qD writing one too many bytes into a region "
"of a size that depends on %<strlen%>",
- stmt, writefn)
+ writefn)
: warning_at (loc, OPT_Wstringop_overflow_,
- "%Gwriting one too many bytes into a region "
- "of a size that depends on %<strlen%>",
- stmt));
+ "writing one too many bytes into a region "
+ "of a size that depends on %<strlen%>"));
}
else if (lenrng[0] == lenrng[1])
{
@@ -2036,65 +2035,65 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry,
warned = (writefn
? warning_n (loc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
- "%G%qD writing %wu byte into a region "
+ "%qD writing %wu byte into a region "
"of size %wu",
- "%G%qD writing %wu bytes into a region "
+ "%qD writing %wu bytes into a region "
"of size %wu",
- stmt, writefn, lenrng[0].to_uhwi (),
+ writefn, lenrng[0].to_uhwi (),
spcrng[0].to_uhwi ())
: warning_n (loc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
- "%Gwriting %wu byte into a region "
+ "writing %wu byte into a region "
"of size %wu",
- "%Gwriting %wu bytes into a region "
+ "writing %wu bytes into a region "
"of size %wu",
- stmt, lenrng[0].to_uhwi (),
+ lenrng[0].to_uhwi (),
spcrng[0].to_uhwi ()));
else
warned = (writefn
? warning_n (loc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
- "%G%qD writing %wu byte into a region "
+ "%qD writing %wu byte into a region "
"of size between %wu and %wu",
- "%G%qD writing %wu bytes into a region "
+ "%qD writing %wu bytes into a region "
"of size between %wu and %wu",
- stmt, writefn, lenrng[0].to_uhwi (),
+ writefn, lenrng[0].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
: warning_n (loc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
- "%Gwriting %wu byte into a region "
+ "writing %wu byte into a region "
"of size between %wu and %wu",
- "%Gwriting %wu bytes into a region "
+ "writing %wu bytes into a region "
"of size between %wu and %wu",
- stmt, lenrng[0].to_uhwi (),
+ lenrng[0].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));
}
else if (spcrng[0] == spcrng[1])
warned = (writefn
? warning_at (loc, OPT_Wstringop_overflow_,
- "%G%qD writing between %wu and %wu bytes "
+ "%qD writing between %wu and %wu bytes "
"into a region of size %wu",
- stmt, writefn, lenrng[0].to_uhwi (),
+ writefn, lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi ())
: warning_at (loc, OPT_Wstringop_overflow_,
- "%Gwriting between %wu and %wu bytes "
+ "writing between %wu and %wu bytes "
"into a region of size %wu",
- stmt, lenrng[0].to_uhwi (),
+ lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi ()));
else
warned = (writefn
? warning_at (loc, OPT_Wstringop_overflow_,
- "%G%qD writing between %wu and %wu bytes "
+ "%qD writing between %wu and %wu bytes "
"into a region of size between %wu and %wu",
- stmt, writefn, lenrng[0].to_uhwi (),
+ writefn, lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
: warning_at (loc, OPT_Wstringop_overflow_,
- "%Gwriting between %wu and %wu bytes "
+ "writing between %wu and %wu bytes "
"into a region of size between %wu and %wu",
- stmt, lenrng[0].to_uhwi (),
+ lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));
@@ -2985,13 +2984,13 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
return warning_n (callloc, OPT_Wstringop_truncation,
cntrange[0].to_uhwi (),
- "%G%qD output truncated before terminating "
+ "%qD output truncated before terminating "
"nul copying %E byte from a string of the "
"same length",
- "%G%qD output truncated before terminating nul "
+ "%qD output truncated before terminating nul "
"copying %E bytes from a string of the same "
"length",
- stmt, func, cnt);
+ func, cnt);
else if (!cat_dstlen_bounded)
{
if (wi::geu_p (lenrange[0], cntrange[1]))
@@ -3001,16 +3000,16 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
if (cntrange[0] == cntrange[1])
return warning_n (callloc, OPT_Wstringop_truncation,
cntrange[0].to_uhwi (),
- "%G%qD output truncated copying %E byte "
+ "%qD output truncated copying %E byte "
"from a string of length %wu",
- "%G%qD output truncated copying %E bytes "
+ "%qD output truncated copying %E bytes "
"from a string of length %wu",
- stmt, func, cnt, lenrange[0].to_uhwi ());
+ func, cnt, lenrange[0].to_uhwi ());
return warning_at (callloc, OPT_Wstringop_truncation,
- "%G%qD output truncated copying between %wu "
+ "%qD output truncated copying between %wu "
"and %wu bytes from a string of length %wu",
- stmt, func, cntrange[0].to_uhwi (),
+ func, cntrange[0].to_uhwi (),
cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
}
else if (wi::geu_p (lenrange[1], cntrange[1]))
@@ -3020,16 +3019,16 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
if (cntrange[0] == cntrange[1])
return warning_n (callloc, OPT_Wstringop_truncation,
cntrange[0].to_uhwi (),
- "%G%qD output may be truncated copying %E "
+ "%qD output may be truncated copying %E "
"byte from a string of length %wu",
- "%G%qD output may be truncated copying %E "
+ "%qD output may be truncated copying %E "
"bytes from a string of length %wu",
- stmt, func, cnt, lenrange[1].to_uhwi ());
+ func, cnt, lenrange[1].to_uhwi ());
return warning_at (callloc, OPT_Wstringop_truncation,
- "%G%qD output may be truncated copying between "
+ "%qD output may be truncated copying between "
"%wu and %wu bytes from a string of length %wu",
- stmt, func, cntrange[0].to_uhwi (),
+ func, cntrange[0].to_uhwi (),
cntrange[1].to_uhwi (), lenrange[1].to_uhwi ());
}
}
@@ -3043,9 +3042,9 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
the lower bound of the specified count but shorter than the
upper bound the copy may (but need not) be truncated. */
return warning_at (callloc, OPT_Wstringop_truncation,
- "%G%qD output may be truncated copying between "
+ "%qD output may be truncated copying between "
"%wu and %wu bytes from a string of length %wu",
- stmt, func, cntrange[0].to_uhwi (),
+ func, cntrange[0].to_uhwi (),
cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
}
}
@@ -3072,8 +3071,8 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
if (cntrange[0] == cntrange[1])
return warning_at (callloc, OPT_Wstringop_truncation,
- "%G%qD specified bound %E equals destination size",
- stmt, func, cnt);
+ "%qD specified bound %E equals destination size",
+ func, cnt);
}
return false;
@@ -3197,9 +3196,9 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
&& sisrc == silen
&& is_strlen_related_p (src, len)
&& warning_at (callloc, OPT_Wstringop_truncation,
- "%G%qD output truncated before terminating nul "
+ "%qD output truncated before terminating nul "
"copying as many bytes from a string as its length",
- stmt, func))
+ func))
warned = true;
else if ((append_p || !dstsize || len == dstlenp1)
&& silen && is_strlen_related_p (src, silen->ptr))
@@ -3210,9 +3209,9 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
opt_code opt = (append_p || dstsize
? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation);
warned = warning_at (callloc, opt,
- "%G%qD specified bound depends on the length "
+ "%qD specified bound depends on the length "
"of the source argument",
- stmt, func);
+ func);
}
if (warned)
{
@@ -4141,24 +4140,24 @@ maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
if (siz <= minlen && bound == -1)
warned = warning_at (stmt_loc, OPT_Wstring_compare,
(at_least
- ? G_("%G%qD of a string of length %wu or more and "
+ ? G_("%qD of a string of length %wu or more and "
"an array of size %wu evaluates to nonzero")
- : G_("%G%qD of a string of length %wu and an array "
+ : G_("%qD of a string of length %wu and an array "
"of size %wu evaluates to nonzero")),
- stmt, callee, minlen, siz);
+ callee, minlen, siz);
else if (!at_least && siz <= HOST_WIDE_INT_MAX)
{
if (len[0] != HOST_WIDE_INT_MAX && len[1] != HOST_WIDE_INT_MAX)
warned = warning_at (stmt_loc, OPT_Wstring_compare,
- "%G%qD of strings of length %wu and %wu "
+ "%qD of strings of length %wu and %wu "
"and bound of %wu evaluates to nonzero",
- stmt, callee, len[0], len[1], bound);
+ callee, len[0], len[1], bound);
else
warned = warning_at (stmt_loc, OPT_Wstring_compare,
- "%G%qD of a string of length %wu, an array "
+ "%qD of a string of length %wu, an array "
"of size %wu and bound of %wu evaluates to "
"nonzero",
- stmt, callee, minlen, siz, bound);
+ callee, minlen, siz, bound);
}
if (!warned)
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 99442d7..24ac031 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -444,7 +444,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
if (wlims.always_executed)
{
if (warning_at (location, OPT_Wuninitialized,
- "%G%qE is used uninitialized", stmt, rhs))
+ "%qE is used uninitialized", rhs))
{
/* ??? This is only effective for decls as in
gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
@@ -457,7 +457,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
}
else if (wlims.wmaybe_uninit)
warned = warning_at (location, OPT_Wmaybe_uninitialized,
- "%G%qE may be used uninitialized", stmt, rhs);
+ "%qE may be used uninitialized", rhs);
return warned ? base : NULL_TREE;
}
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 012f48b..2909e8a 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -3597,8 +3597,6 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
niter information which is copied from the original loop. */
gcc_assert (loop_constraint_set_p (loop, LOOP_C_FINITE));
vect_free_loop_info_assumptions (nloop);
- /* And set constraint LOOP_C_INFINITE for niter analyzer. */
- loop_constraint_set (loop, LOOP_C_INFINITE);
}
if (LOCATION_LOCUS (vect_location.get_location_t ()) != UNKNOWN_LOCATION
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 51a46a6..bc523d1 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -6516,33 +6516,31 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
stmt_vec_info orig_stmt_of_analysis = stmt_info;
stmt_vec_info phi_info = stmt_info;
- if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def
- || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
+ if (!is_a <gphi *> (stmt_info->stmt))
{
- if (!is_a <gphi *> (stmt_info->stmt))
- {
- STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
- return true;
- }
- if (slp_node)
- {
- slp_node_instance->reduc_phis = slp_node;
- /* ??? We're leaving slp_node to point to the PHIs, we only
- need it to get at the number of vector stmts which wasn't
- yet initialized for the instance root. */
- }
- if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
- stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (stmt_info));
- else /* STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def */
- {
- use_operand_p use_p;
- gimple *use_stmt;
- bool res = single_imm_use (gimple_phi_result (stmt_info->stmt),
- &use_p, &use_stmt);
- gcc_assert (res);
- phi_info = loop_vinfo->lookup_stmt (use_stmt);
- stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (phi_info));
- }
+ STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
+ return true;
+ }
+ if (slp_node)
+ {
+ slp_node_instance->reduc_phis = slp_node;
+ /* ??? We're leaving slp_node to point to the PHIs, we only
+ need it to get at the number of vector stmts which wasn't
+ yet initialized for the instance root. */
+ }
+ if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
+ stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (stmt_info));
+ else
+ {
+ gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info)
+ == vect_double_reduction_def);
+ use_operand_p use_p;
+ gimple *use_stmt;
+ bool res = single_imm_use (gimple_phi_result (stmt_info->stmt),
+ &use_p, &use_stmt);
+ gcc_assert (res);
+ phi_info = loop_vinfo->lookup_stmt (use_stmt);
+ stmt_info = vect_stmt_to_vectorize (STMT_VINFO_REDUC_DEF (phi_info));
}
/* PHIs should not participate in patterns. */
diff --git a/gcc/tree-vect-slp-patterns.c b/gcc/tree-vect-slp-patterns.c
index 2671f91..f774cac 100644
--- a/gcc/tree-vect-slp-patterns.c
+++ b/gcc/tree-vect-slp-patterns.c
@@ -1496,8 +1496,8 @@ complex_operations_pattern::build (vec_info * /* vinfo */)
class addsub_pattern : public vect_pattern
{
public:
- addsub_pattern (slp_tree *node)
- : vect_pattern (node, NULL, IFN_VEC_ADDSUB) {};
+ addsub_pattern (slp_tree *node, internal_fn ifn)
+ : vect_pattern (node, NULL, ifn) {};
void build (vec_info *);
@@ -1510,46 +1510,68 @@ addsub_pattern::recognize (slp_tree_to_load_perm_map_t *, slp_tree *node_)
{
slp_tree node = *node_;
if (SLP_TREE_CODE (node) != VEC_PERM_EXPR
- || SLP_TREE_CHILDREN (node).length () != 2)
+ || SLP_TREE_CHILDREN (node).length () != 2
+ || SLP_TREE_LANE_PERMUTATION (node).length () % 2)
return NULL;
/* Match a blend of a plus and a minus op with the same number of plus and
minus lanes on the same operands. */
- slp_tree sub = SLP_TREE_CHILDREN (node)[0];
- slp_tree add = SLP_TREE_CHILDREN (node)[1];
- bool swapped_p = false;
- if (vect_match_expression_p (sub, PLUS_EXPR))
- {
- std::swap (add, sub);
- swapped_p = true;
- }
- if (!(vect_match_expression_p (add, PLUS_EXPR)
- && vect_match_expression_p (sub, MINUS_EXPR)))
+ unsigned l0 = SLP_TREE_LANE_PERMUTATION (node)[0].first;
+ unsigned l1 = SLP_TREE_LANE_PERMUTATION (node)[1].first;
+ if (l0 == l1)
+ return NULL;
+ bool l0add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0],
+ PLUS_EXPR);
+ if (!l0add_p
+ && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0], MINUS_EXPR))
+ return NULL;
+ bool l1add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1],
+ PLUS_EXPR);
+ if (!l1add_p
+ && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1], MINUS_EXPR))
return NULL;
- if (!((SLP_TREE_CHILDREN (sub)[0] == SLP_TREE_CHILDREN (add)[0]
- && SLP_TREE_CHILDREN (sub)[1] == SLP_TREE_CHILDREN (add)[1])
- || (SLP_TREE_CHILDREN (sub)[0] == SLP_TREE_CHILDREN (add)[1]
- && SLP_TREE_CHILDREN (sub)[1] == SLP_TREE_CHILDREN (add)[0])))
+
+ slp_tree l0node = SLP_TREE_CHILDREN (node)[l0];
+ slp_tree l1node = SLP_TREE_CHILDREN (node)[l1];
+ if (!((SLP_TREE_CHILDREN (l0node)[0] == SLP_TREE_CHILDREN (l1node)[0]
+ && SLP_TREE_CHILDREN (l0node)[1] == SLP_TREE_CHILDREN (l1node)[1])
+ || (SLP_TREE_CHILDREN (l0node)[0] == SLP_TREE_CHILDREN (l1node)[1]
+ && SLP_TREE_CHILDREN (l0node)[1] == SLP_TREE_CHILDREN (l1node)[0])))
return NULL;
for (unsigned i = 0; i < SLP_TREE_LANE_PERMUTATION (node).length (); ++i)
{
std::pair<unsigned, unsigned> perm = SLP_TREE_LANE_PERMUTATION (node)[i];
- if (swapped_p)
- perm.first = perm.first == 0 ? 1 : 0;
- /* It has to be alternating -, +, -, ...
+ /* It has to be alternating -, +, -,
While we could permute the .ADDSUB inputs and the .ADDSUB output
that's only profitable over the add + sub + blend if at least
one of the permute is optimized which we can't determine here. */
- if (perm.first != (i & 1)
+ if (perm.first != ((i & 1) ? l1 : l0)
|| perm.second != i)
return NULL;
}
- if (!vect_pattern_validate_optab (IFN_VEC_ADDSUB, node))
- return NULL;
+ /* Now we have either { -, +, -, + ... } (!l0add_p) or { +, -, +, - ... }
+ (l0add_p), see whether we have FMA variants. */
+ if (!l0add_p
+ && vect_match_expression_p (SLP_TREE_CHILDREN (l0node)[0], MULT_EXPR))
+ {
+ /* (c * d) -+ a */
+ if (vect_pattern_validate_optab (IFN_VEC_FMADDSUB, node))
+ return new addsub_pattern (node_, IFN_VEC_FMADDSUB);
+ }
+ else if (l0add_p
+ && vect_match_expression_p (SLP_TREE_CHILDREN (l1node)[0], MULT_EXPR))
+ {
+ /* (c * d) +- a */
+ if (vect_pattern_validate_optab (IFN_VEC_FMSUBADD, node))
+ return new addsub_pattern (node_, IFN_VEC_FMSUBADD);
+ }
- return new addsub_pattern (node_);
+ if (!l0add_p && vect_pattern_validate_optab (IFN_VEC_ADDSUB, node))
+ return new addsub_pattern (node_, IFN_VEC_ADDSUB);
+
+ return NULL;
}
void
@@ -1557,38 +1579,96 @@ addsub_pattern::build (vec_info *vinfo)
{
slp_tree node = *m_node;
- slp_tree sub = SLP_TREE_CHILDREN (node)[0];
- slp_tree add = SLP_TREE_CHILDREN (node)[1];
- if (vect_match_expression_p (sub, PLUS_EXPR))
- std::swap (add, sub);
-
- /* Modify the blend node in-place. */
- SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (sub)[0];
- SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (sub)[1];
- SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[0])++;
- SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[1])++;
-
- /* Build IFN_VEC_ADDSUB from the sub representative operands. */
- stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (sub);
- gcall *call = gimple_build_call_internal (IFN_VEC_ADDSUB, 2,
- gimple_assign_rhs1 (rep->stmt),
- gimple_assign_rhs2 (rep->stmt));
- gimple_call_set_lhs (call, make_ssa_name
- (TREE_TYPE (gimple_assign_lhs (rep->stmt))));
- gimple_call_set_nothrow (call, true);
- gimple_set_bb (call, gimple_bb (rep->stmt));
- stmt_vec_info new_rep = vinfo->add_pattern_stmt (call, rep);
- SLP_TREE_REPRESENTATIVE (node) = new_rep;
- STMT_VINFO_RELEVANT (new_rep) = vect_used_in_scope;
- STMT_SLP_TYPE (new_rep) = pure_slp;
- STMT_VINFO_VECTYPE (new_rep) = SLP_TREE_VECTYPE (node);
- STMT_VINFO_SLP_VECT_ONLY_PATTERN (new_rep) = true;
- STMT_VINFO_REDUC_DEF (new_rep) = STMT_VINFO_REDUC_DEF (vect_orig_stmt (rep));
- SLP_TREE_CODE (node) = ERROR_MARK;
- SLP_TREE_LANE_PERMUTATION (node).release ();
-
- vect_free_slp_tree (sub);
- vect_free_slp_tree (add);
+ unsigned l0 = SLP_TREE_LANE_PERMUTATION (node)[0].first;
+ unsigned l1 = SLP_TREE_LANE_PERMUTATION (node)[1].first;
+
+ switch (m_ifn)
+ {
+ case IFN_VEC_ADDSUB:
+ {
+ slp_tree sub = SLP_TREE_CHILDREN (node)[l0];
+ slp_tree add = SLP_TREE_CHILDREN (node)[l1];
+
+ /* Modify the blend node in-place. */
+ SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (sub)[0];
+ SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (sub)[1];
+ SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[0])++;
+ SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[1])++;
+
+ /* Build IFN_VEC_ADDSUB from the sub representative operands. */
+ stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (sub);
+ gcall *call = gimple_build_call_internal (IFN_VEC_ADDSUB, 2,
+ gimple_assign_rhs1 (rep->stmt),
+ gimple_assign_rhs2 (rep->stmt));
+ gimple_call_set_lhs (call, make_ssa_name
+ (TREE_TYPE (gimple_assign_lhs (rep->stmt))));
+ gimple_call_set_nothrow (call, true);
+ gimple_set_bb (call, gimple_bb (rep->stmt));
+ stmt_vec_info new_rep = vinfo->add_pattern_stmt (call, rep);
+ SLP_TREE_REPRESENTATIVE (node) = new_rep;
+ STMT_VINFO_RELEVANT (new_rep) = vect_used_in_scope;
+ STMT_SLP_TYPE (new_rep) = pure_slp;
+ STMT_VINFO_VECTYPE (new_rep) = SLP_TREE_VECTYPE (node);
+ STMT_VINFO_SLP_VECT_ONLY_PATTERN (new_rep) = true;
+ STMT_VINFO_REDUC_DEF (new_rep) = STMT_VINFO_REDUC_DEF (vect_orig_stmt (rep));
+ SLP_TREE_CODE (node) = ERROR_MARK;
+ SLP_TREE_LANE_PERMUTATION (node).release ();
+
+ vect_free_slp_tree (sub);
+ vect_free_slp_tree (add);
+ break;
+ }
+ case IFN_VEC_FMADDSUB:
+ case IFN_VEC_FMSUBADD:
+ {
+ slp_tree sub, add;
+ if (m_ifn == IFN_VEC_FMADDSUB)
+ {
+ sub = SLP_TREE_CHILDREN (node)[l0];
+ add = SLP_TREE_CHILDREN (node)[l1];
+ }
+ else /* m_ifn == IFN_VEC_FMSUBADD */
+ {
+ sub = SLP_TREE_CHILDREN (node)[l1];
+ add = SLP_TREE_CHILDREN (node)[l0];
+ }
+ slp_tree mul = SLP_TREE_CHILDREN (sub)[0];
+ /* Modify the blend node in-place. */
+ SLP_TREE_CHILDREN (node).safe_grow (3, true);
+ SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (mul)[0];
+ SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (mul)[1];
+ SLP_TREE_CHILDREN (node)[2] = SLP_TREE_CHILDREN (sub)[1];
+ SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[0])++;
+ SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[1])++;
+ SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[2])++;
+
+ /* Build IFN_VEC_FMADDSUB from the mul/sub representative operands. */
+ stmt_vec_info srep = SLP_TREE_REPRESENTATIVE (sub);
+ stmt_vec_info mrep = SLP_TREE_REPRESENTATIVE (mul);
+ gcall *call = gimple_build_call_internal (m_ifn, 3,
+ gimple_assign_rhs1 (mrep->stmt),
+ gimple_assign_rhs2 (mrep->stmt),
+ gimple_assign_rhs2 (srep->stmt));
+ gimple_call_set_lhs (call, make_ssa_name
+ (TREE_TYPE (gimple_assign_lhs (srep->stmt))));
+ gimple_call_set_nothrow (call, true);
+ gimple_set_bb (call, gimple_bb (srep->stmt));
+ stmt_vec_info new_rep = vinfo->add_pattern_stmt (call, srep);
+ SLP_TREE_REPRESENTATIVE (node) = new_rep;
+ STMT_VINFO_RELEVANT (new_rep) = vect_used_in_scope;
+ STMT_SLP_TYPE (new_rep) = pure_slp;
+ STMT_VINFO_VECTYPE (new_rep) = SLP_TREE_VECTYPE (node);
+ STMT_VINFO_SLP_VECT_ONLY_PATTERN (new_rep) = true;
+ STMT_VINFO_REDUC_DEF (new_rep) = STMT_VINFO_REDUC_DEF (vect_orig_stmt (srep));
+ SLP_TREE_CODE (node) = ERROR_MARK;
+ SLP_TREE_LANE_PERMUTATION (node).release ();
+
+ vect_free_slp_tree (sub);
+ vect_free_slp_tree (add);
+ break;
+ }
+ default:;
+ }
}
/*******************************************************************************
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 9155af4..5357cd0 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -3470,16 +3470,19 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
struct slpg_vertex
{
slpg_vertex (slp_tree node_)
- : node (node_), perm_out (-1), materialize (0) {}
+ : node (node_), perm_in (-1), perm_out (-1) {}
- int get_perm_in () const { return materialize ? materialize : perm_out; }
+ int get_perm_materialized () const
+ { return perm_in != perm_out ? perm_in : 0; }
slp_tree node;
- /* The permutation on the outgoing lanes (towards SLP parents). */
+ /* The common permutation on the incoming lanes (towards SLP children). */
+ int perm_in;
+ /* The permutation on the outgoing lanes (towards SLP parents). When
+ the node is a materialization point for a permute this differs
+ from perm_in (and is then usually zero). Materialization happens
+ on the input side. */
int perm_out;
- /* The permutation that is applied by this node. perm_out is
- relative to this. */
- int materialize;
};
/* Fill the vertices and leafs vector with all nodes in the SLP graph. */
@@ -3614,7 +3617,11 @@ vect_optimize_slp (vec_info *vinfo)
/* Leafs do not change across iterations. Note leafs also double
as entries to the reverse graph. */
if (!slpg->vertices[idx].succ)
- vertices[idx].perm_out = 0;
+ {
+ vertices[idx].perm_in = 0;
+ vertices[idx].perm_out = 0;
+ }
+
/* Loads are the only thing generating permutes. */
if (!SLP_TREE_LOAD_PERMUTATION (node).exists ())
continue;
@@ -3663,6 +3670,7 @@ vect_optimize_slp (vec_info *vinfo)
for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
perm[j] = SLP_TREE_LOAD_PERMUTATION (node)[j] - imin;
perms.safe_push (perm);
+ vertices[idx].perm_in = perms.length () - 1;
vertices[idx].perm_out = perms.length () - 1;
}
@@ -3702,8 +3710,11 @@ vect_optimize_slp (vec_info *vinfo)
if (STMT_VINFO_DATA_REF (rep)
&& DR_IS_WRITE (STMT_VINFO_DATA_REF (rep)))
{
+ /* ??? We're forcing materialization in place
+ of the child here, we'd need special handling
+ in materialization to leave perm_in -1 here. */
+ vertices[idx].perm_in = 0;
vertices[idx].perm_out = 0;
- continue;
}
/* We cannot move a permute across an operation that is
not independent on lanes. Note this is an explicit
@@ -3717,19 +3728,21 @@ vect_optimize_slp (vec_info *vinfo)
case CFN_COMPLEX_MUL:
case CFN_COMPLEX_MUL_CONJ:
case CFN_VEC_ADDSUB:
+ case CFN_VEC_FMADDSUB:
+ case CFN_VEC_FMSUBADD:
+ vertices[idx].perm_in = 0;
vertices[idx].perm_out = 0;
- continue;
default:;
}
}
- int perm;
if (!slpg->vertices[idx].succ)
/* Pick up pre-computed leaf values. */
- perm = vertices[idx].perm_out;
+ ;
else
{
- perm = vertices[idx].get_perm_in ();
+ bool any_succ_perm_out_m1 = false;
+ int perm_in = vertices[idx].perm_in;
for (graph_edge *succ = slpg->vertices[idx].succ;
succ; succ = succ->succ_next)
{
@@ -3742,51 +3755,65 @@ vect_optimize_slp (vec_info *vinfo)
For example see gcc.dg/vect/bb-slp-14.c for a case
that would break. */
if (succ_perm == -1)
- continue;
- if (perm == -1)
- perm = succ_perm;
+ {
+ /* When we handled a non-leaf optimistically, note
+ that so we can adjust its outgoing permute below. */
+ slp_tree succ_node = vertices[succ_idx].node;
+ if (SLP_TREE_DEF_TYPE (succ_node) != vect_external_def
+ && SLP_TREE_DEF_TYPE (succ_node) != vect_constant_def)
+ any_succ_perm_out_m1 = true;
+ continue;
+ }
+ if (perm_in == -1)
+ perm_in = succ_perm;
else if (succ_perm == 0
- || !vect_slp_perms_eq (perms, perm, succ_perm))
+ || !vect_slp_perms_eq (perms, perm_in, succ_perm))
{
- perm = 0;
+ perm_in = 0;
break;
}
}
- /* If this is a node we do not want to eventually unshare
- but it can be permuted at will, verify all users have
- the same permutations registered and otherwise drop to
- zero. */
- if (perm == -1
- && SLP_TREE_DEF_TYPE (node) != vect_external_def
- && SLP_TREE_DEF_TYPE (node) != vect_constant_def)
+ /* Adjust any incoming permutes we treated optimistically. */
+ if (perm_in != -1 && any_succ_perm_out_m1)
{
- int preds_perm = -1;
- for (graph_edge *pred = slpg->vertices[idx].pred;
- pred; pred = pred->pred_next)
+ for (graph_edge *succ = slpg->vertices[idx].succ;
+ succ; succ = succ->succ_next)
{
- int pred_perm = vertices[pred->src].get_perm_in ();
- if (preds_perm == -1)
- preds_perm = pred_perm;
- else if (!vect_slp_perms_eq (perms,
- pred_perm, preds_perm))
- perm = 0;
+ slp_tree succ_node = vertices[succ->dest].node;
+ if (vertices[succ->dest].perm_out == -1
+ && SLP_TREE_DEF_TYPE (succ_node) != vect_external_def
+ && SLP_TREE_DEF_TYPE (succ_node) != vect_constant_def)
+ {
+ vertices[succ->dest].perm_out = perm_in;
+ /* And ensure this propagates. */
+ if (vertices[succ->dest].perm_in == -1)
+ vertices[succ->dest].perm_in = perm_in;
+ }
}
+ changed = true;
}
- if (!vect_slp_perms_eq (perms, perm,
- vertices[idx].get_perm_in ()))
+ if (!vect_slp_perms_eq (perms, perm_in,
+ vertices[idx].perm_in))
{
/* Make sure we eventually converge. */
- gcc_checking_assert (vertices[idx].get_perm_in () == -1
- || perm == 0);
- if (perm == 0)
- {
- vertices[idx].perm_out = 0;
- vertices[idx].materialize = 0;
- }
- if (!vertices[idx].materialize)
- vertices[idx].perm_out = perm;
+ gcc_checking_assert (vertices[idx].perm_in == -1
+ || perm_in == 0);
+ vertices[idx].perm_in = perm_in;
+
+ /* While we can handle VEC_PERM nodes as transparent
+ pass-through they can be a cheap materialization
+ point as well. In addition they can act as source
+ of a random permutation as well.
+ The following ensures that former materialization
+ points that now have zero incoming permutes no
+ longer appear as such and that former "any" permutes
+ get pass-through. We keep VEC_PERM nodes optimistic
+ as "any" outgoing permute though. */
+ if (vertices[idx].perm_out != 0
+ && SLP_TREE_CODE (node) != VEC_PERM_EXPR)
+ vertices[idx].perm_out = perm_in;
changed = true;
}
}
@@ -3796,25 +3823,19 @@ vect_optimize_slp (vec_info *vinfo)
if (!do_materialization)
continue;
+ int perm = vertices[idx].perm_out;
if (perm == 0 || perm == -1)
continue;
/* Decide on permute materialization. Look whether there's
a use (pred) edge that is permuted differently than us.
- In that case mark ourselves so the permutation is applied.
- For VEC_PERM_EXPRs the permutation doesn't carry along
- from children to parents so force materialization at the
- point of the VEC_PERM_EXPR. In principle VEC_PERM_EXPRs
- are a source of an arbitrary permutation again, similar
- to constants/externals - that's something we do not yet
- optimally handle. */
- bool all_preds_permuted = (SLP_TREE_CODE (node) != VEC_PERM_EXPR
- && slpg->vertices[idx].pred != NULL);
+ In that case mark ourselves so the permutation is applied. */
+ bool all_preds_permuted = slpg->vertices[idx].pred != NULL;
if (all_preds_permuted)
for (graph_edge *pred = slpg->vertices[idx].pred;
pred; pred = pred->pred_next)
{
- int pred_perm = vertices[pred->src].get_perm_in ();
+ int pred_perm = vertices[pred->src].perm_in;
gcc_checking_assert (pred_perm != -1);
if (!vect_slp_perms_eq (perms, perm, pred_perm))
{
@@ -3824,10 +3845,8 @@ vect_optimize_slp (vec_info *vinfo)
}
if (!all_preds_permuted)
{
- if (!vertices[idx].materialize)
- changed = true;
- vertices[idx].materialize = perm;
vertices[idx].perm_out = 0;
+ changed = true;
}
}
@@ -3840,91 +3859,48 @@ vect_optimize_slp (vec_info *vinfo)
}
}
while (changed);
- statistics_counter_event (cfun, "SLP optimize perm iterations", iteration);
-
- /* Compute pre-order. */
- auto_vec<int> heads;
- heads.reserve (vinfo->slp_instances.length ());
- for (slp_instance inst : vinfo->slp_instances)
- heads.quick_push (SLP_INSTANCE_TREE (inst)->vertex);
- auto_vec<int> po;
- graphds_dfs (slpg, &heads[0], heads.length (), &po, true, NULL, NULL);
-
- /* Propagate materialized permutes to "any" permute nodes. For heads
- ending up as "any" (reductions with just invariants), set them to
- no permute. */
- for (int idx : heads)
- if (vertices[idx].perm_out == -1)
- vertices[idx].perm_out = 0;
- for (i = po.length (); i > 0; --i)
- {
- int idx = po[i-1];
- int perm_in = vertices[idx].get_perm_in ();
- slp_tree node = vertices[idx].node;
- if (SLP_TREE_DEF_TYPE (node) == vect_external_def
- || SLP_TREE_DEF_TYPE (node) == vect_constant_def)
- continue;
- gcc_assert (perm_in != -1);
- for (graph_edge *succ = slpg->vertices[idx].succ;
- succ; succ = succ->succ_next)
- {
- slp_tree succ_node = vertices[succ->dest].node;
- if (SLP_TREE_DEF_TYPE (succ_node) == vect_external_def
- || SLP_TREE_DEF_TYPE (succ_node) == vect_constant_def)
- continue;
- if (vertices[succ->dest].perm_out == -1)
- vertices[succ->dest].perm_out = perm_in;
- else
- /* Propagation should have ensured that all preds have the same
- permutation. */
- gcc_assert (vect_slp_perms_eq (perms, perm_in,
- vertices[succ->dest].perm_out));
- }
- }
+ statistics_histogram_event (cfun, "SLP optimize perm iterations", iteration);
/* Materialize. */
for (i = 0; i < vertices.length (); ++i)
{
- int perm = vertices[i].get_perm_in ();
- if (perm <= 0)
- continue;
-
+ int perm_in = vertices[i].perm_in;
slp_tree node = vertices[i].node;
- /* First permute invariant/external original successors. */
+ /* First permute invariant/external original successors, we handle
+ those optimistically during propagation and duplicate them if
+ they are used with different permutations. */
unsigned j;
slp_tree child;
- FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
- {
- if (!child
- || (SLP_TREE_DEF_TYPE (child) != vect_constant_def
- && SLP_TREE_DEF_TYPE (child) != vect_external_def))
- continue;
+ if (perm_in > 0)
+ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+ {
+ if (!child
+ || (SLP_TREE_DEF_TYPE (child) != vect_constant_def
+ && SLP_TREE_DEF_TYPE (child) != vect_external_def))
+ continue;
- /* If the vector is uniform there's nothing to do. */
- if (vect_slp_tree_uniform_p (child))
- continue;
+ /* If the vector is uniform there's nothing to do. */
+ if (vect_slp_tree_uniform_p (child))
+ continue;
- /* We can end up sharing some externals via two_operator
- handling. Be prepared to unshare those. */
- if (child->refcnt != 1)
- {
- gcc_assert (slpg->vertices[child->vertex].pred->pred_next);
- SLP_TREE_CHILDREN (node)[j] = child
- = vect_create_new_slp_node
- (SLP_TREE_SCALAR_OPS (child).copy ());
- }
- vect_slp_permute (perms[perm],
- SLP_TREE_SCALAR_OPS (child), true);
- }
+ /* We can end up sharing some externals via two_operator
+ handling. Be prepared to unshare those. */
+ if (child->refcnt != 1)
+ {
+ gcc_assert (slpg->vertices[child->vertex].pred->pred_next);
+ SLP_TREE_CHILDREN (node)[j] = child
+ = vect_create_new_slp_node
+ (SLP_TREE_SCALAR_OPS (child).copy ());
+ }
+ vect_slp_permute (perms[perm_in],
+ SLP_TREE_SCALAR_OPS (child), true);
+ }
- if (vertices[i].materialize)
+ if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
{
- if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
- /* For loads simply drop the permutation, the load permutation
- already performs the desired permutation. */
- ;
- else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ /* Apply the common permutes to the input vectors. */
+ if (perm_in > 0)
{
/* If the node is already a permute node we can apply
the permutation to the lane selection, effectively
@@ -3933,12 +3909,30 @@ vect_optimize_slp (vec_info *vinfo)
dump_printf_loc (MSG_NOTE, vect_location,
"simplifying permute node %p\n",
node);
-
for (unsigned k = 0;
k < SLP_TREE_LANE_PERMUTATION (node).length (); ++k)
SLP_TREE_LANE_PERMUTATION (node)[k].second
- = perms[perm][SLP_TREE_LANE_PERMUTATION (node)[k].second];
+ = perms[perm_in][SLP_TREE_LANE_PERMUTATION (node)[k].second];
}
+ /* Apply the anticipated output permute to the permute and
+ stmt vectors. */
+ int perm_out = vertices[i].perm_out;
+ if (perm_out > 0)
+ {
+ vect_slp_permute (perms[perm_out],
+ SLP_TREE_SCALAR_STMTS (node), true);
+ vect_slp_permute (perms[perm_out],
+ SLP_TREE_LANE_PERMUTATION (node), true);
+ }
+ }
+ else if (vertices[i].get_perm_materialized () != 0)
+ {
+ if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
+ /* For loads simply drop the permutation, the load permutation
+ already performs the desired permutation. */
+ ;
+ else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ gcc_unreachable ();
else
{
if (dump_enabled_p ())
@@ -3953,7 +3947,7 @@ vect_optimize_slp (vec_info *vinfo)
SLP_TREE_CHILDREN (node) = vNULL;
SLP_TREE_SCALAR_STMTS (copy)
= SLP_TREE_SCALAR_STMTS (node).copy ();
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_SCALAR_STMTS (copy), true);
gcc_assert (!SLP_TREE_SCALAR_OPS (node).exists ());
SLP_TREE_REPRESENTATIVE (copy) = SLP_TREE_REPRESENTATIVE (node);
@@ -3973,28 +3967,31 @@ vect_optimize_slp (vec_info *vinfo)
SLP_TREE_LANE_PERMUTATION (node).create (SLP_TREE_LANES (node));
for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
SLP_TREE_LANE_PERMUTATION (node)
- .quick_push (std::make_pair (0, perms[perm][j]));
+ .quick_push (std::make_pair (0, perms[perm_in][j]));
SLP_TREE_CODE (node) = VEC_PERM_EXPR;
}
}
- else
+ else if (perm_in > 0) /* perm_in == perm_out */
{
/* Apply the reverse permutation to our stmts. */
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_SCALAR_STMTS (node), true);
- /* And to the load permutation, which we can simply
+ /* And to the lane/load permutation, which we can simply
make regular by design. */
if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
{
+ gcc_assert (!SLP_TREE_LANE_PERMUTATION (node).exists ());
/* ??? When we handle non-bijective permutes the idea
is that we can force the load-permutation to be
{ min, min + 1, min + 2, ... max }. But then the
scalar defs might no longer match the lane content
which means wrong-code with live lane vectorization.
So we possibly have to have NULL entries for those. */
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_LOAD_PERMUTATION (node), true);
}
+ else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ gcc_unreachable ();
}
}
@@ -4028,14 +4025,14 @@ vect_optimize_slp (vec_info *vinfo)
}
else if (SLP_TREE_LOAD_PERMUTATION (old).exists ()
&& SLP_TREE_REF_COUNT (old) == 1
- && vertices[old->vertex].materialize)
+ && vertices[old->vertex].get_perm_materialized () != 0)
{
/* ??? For loads the situation is more complex since
we can't modify the permute in place in case the
node is used multiple times. In fact for loads this
should be somehow handled in the propagation engine. */
/* Apply the reverse permutation to our stmts. */
- int perm = vertices[old->vertex].get_perm_in ();
+ int perm = vertices[old->vertex].get_perm_materialized ();
vect_slp_permute (perms[perm],
SLP_TREE_SCALAR_STMTS (old), true);
vect_slp_permute (perms[perm],
@@ -7105,6 +7102,21 @@ vect_schedule_slp_node (vec_info *vinfo,
gcc_assert (seen_vector_def);
si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
}
+ else if (is_a <bb_vec_info> (vinfo)
+ && gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt)
+ && gimple_could_trap_p (stmt_info->stmt))
+ {
+ /* We've constrained possibly trapping operations to all come
+ from the same basic-block, if vectorized defs would allow earlier
+ scheduling still force vectorized stmts to the original block.
+ This is only necessary for BB vectorization since for loop vect
+ all operations are in a single BB and scalar stmt based
+ placement doesn't play well with epilogue vectorization. */
+ gcc_assert (dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (stmt_info->stmt),
+ gimple_bb (last_stmt)));
+ si = gsi_after_labels (gimple_bb (stmt_info->stmt));
+ }
else if (is_a <gphi *> (last_stmt))
si = gsi_after_labels (gimple_bb (last_stmt));
else
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 4ee11b2..e590f34 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2439,17 +2439,31 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
return true;
}
-/* Return true if boolean argument MASK is suitable for vectorizing
- conditional operation STMT_INFO. When returning true, store the type
- of the definition in *MASK_DT_OUT and the type of the vectorized mask
- in *MASK_VECTYPE_OUT. */
+/* Return true if boolean argument at MASK_INDEX is suitable for vectorizing
+ conditional operation STMT_INFO. When returning true, store the mask
+ in *MASK, the type of its definition in *MASK_DT_OUT, the type of the
+ vectorized mask in *MASK_VECTYPE_OUT and the SLP node corresponding
+ to the mask in *MASK_NODE if MASK_NODE is not NULL. */
static bool
-vect_check_scalar_mask (vec_info *vinfo, stmt_vec_info stmt_info, tree mask,
- vect_def_type *mask_dt_out,
- tree *mask_vectype_out)
+vect_check_scalar_mask (vec_info *vinfo, stmt_vec_info stmt_info,
+ slp_tree slp_node, unsigned mask_index,
+ tree *mask, slp_tree *mask_node,
+ vect_def_type *mask_dt_out, tree *mask_vectype_out)
{
- if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask)))
+ enum vect_def_type mask_dt;
+ tree mask_vectype;
+ slp_tree mask_node_1;
+ if (!vect_is_simple_use (vinfo, stmt_info, slp_node, mask_index,
+ mask, &mask_node_1, &mask_dt, &mask_vectype))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "mask use not simple.\n");
+ return false;
+ }
+
+ if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (*mask)))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2457,7 +2471,7 @@ vect_check_scalar_mask (vec_info *vinfo, stmt_vec_info stmt_info, tree mask,
return false;
}
- if (TREE_CODE (mask) != SSA_NAME)
+ if (TREE_CODE (*mask) != SSA_NAME)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2465,13 +2479,15 @@ vect_check_scalar_mask (vec_info *vinfo, stmt_vec_info stmt_info, tree mask,
return false;
}
- enum vect_def_type mask_dt;
- tree mask_vectype;
- if (!vect_is_simple_use (mask, vinfo, &mask_dt, &mask_vectype))
+ /* If the caller is not prepared for adjusting an external/constant
+ SLP mask vector type fail. */
+ if (slp_node
+ && !mask_node
+ && SLP_TREE_DEF_TYPE (mask_node_1) != vect_internal_def)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "mask use not simple.\n");
+ "SLP mask argument is not vectorized.\n");
return false;
}
@@ -2501,6 +2517,8 @@ vect_check_scalar_mask (vec_info *vinfo, stmt_vec_info stmt_info, tree mask,
*mask_dt_out = mask_dt;
*mask_vectype_out = mask_vectype;
+ if (mask_node)
+ *mask_node = mask_node_1;
return true;
}
@@ -2525,10 +2543,18 @@ vect_check_store_rhs (vec_info *vinfo, stmt_vec_info stmt_info,
return false;
}
+ unsigned op_no = 0;
+ if (gcall *call = dyn_cast <gcall *> (stmt_info->stmt))
+ {
+ if (gimple_call_internal_p (call)
+ && internal_store_fn_p (gimple_call_internal_fn (call)))
+ op_no = internal_fn_stored_value_index (gimple_call_internal_fn (call));
+ }
+
enum vect_def_type rhs_dt;
tree rhs_vectype;
slp_tree slp_op;
- if (!vect_is_simple_use (vinfo, stmt_info, slp_node, 0,
+ if (!vect_is_simple_use (vinfo, stmt_info, slp_node, op_no,
&rhs, &slp_op, &rhs_dt, &rhs_vectype))
{
if (dump_enabled_p ())
@@ -3163,9 +3189,8 @@ vectorizable_call (vec_info *vinfo,
{
if ((int) i == mask_opno)
{
- op = gimple_call_arg (stmt, i);
- if (!vect_check_scalar_mask (vinfo,
- stmt_info, op, &dt[i], &vectypes[i]))
+ if (!vect_check_scalar_mask (vinfo, stmt_info, slp_node, mask_opno,
+ &op, &slp_op[i], &dt[i], &vectypes[i]))
return false;
continue;
}
@@ -7213,13 +7238,10 @@ vectorizable_store (vec_info *vinfo,
}
int mask_index = internal_fn_mask_index (ifn);
- if (mask_index >= 0)
- {
- mask = gimple_call_arg (call, mask_index);
- if (!vect_check_scalar_mask (vinfo, stmt_info, mask, &mask_dt,
- &mask_vectype))
- return false;
- }
+ if (mask_index >= 0
+ && !vect_check_scalar_mask (vinfo, stmt_info, slp_node, mask_index,
+ &mask, NULL, &mask_dt, &mask_vectype))
+ return false;
}
op = vect_get_store_rhs (stmt_info);
@@ -8494,13 +8516,13 @@ vectorizable_load (vec_info *vinfo,
return false;
int mask_index = internal_fn_mask_index (ifn);
- if (mask_index >= 0)
- {
- mask = gimple_call_arg (call, mask_index);
- if (!vect_check_scalar_mask (vinfo, stmt_info, mask, &mask_dt,
- &mask_vectype))
- return false;
- }
+ if (mask_index >= 0
+ && !vect_check_scalar_mask (vinfo, stmt_info, slp_node,
+ /* ??? For SLP we only have operands for
+ the mask operand. */
+ slp_node ? 0 : mask_index,
+ &mask, NULL, &mask_dt, &mask_vectype))
+ return false;
}
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -11484,13 +11506,7 @@ vect_is_simple_use (vec_info *vinfo, stmt_vec_info stmt, slp_tree slp_node,
*op = gimple_op (ass, operand + 1);
}
else if (gcall *call = dyn_cast <gcall *> (stmt->stmt))
- {
- if (gimple_call_internal_p (call)
- && internal_store_fn_p (gimple_call_internal_fn (call)))
- operand = internal_fn_stored_value_index (gimple_call_internal_fn
- (call));
- *op = gimple_call_arg (call, operand);
- }
+ *op = gimple_call_arg (call, operand);
else
gcc_unreachable ();
return vect_is_simple_use (*op, vinfo, dt, vectype, def_stmt_info_out);